Does Json.NET's JToken.SelectTokens method guarantee order?
E.g. given this data:
{
"items": [
{ "name": "foo" },
{ "name": "bar" }
]
}
Will this expression: obj.SelectTokens("items..name") always return ['foo', 'bar']?
Specifically, I'm interested in expected behaviour for doing this across multiple arrays, like:
{
"items": [
{ "name": "foo" },
{ "name": "bar" }
]
}
{
"values": [
{ "quantity": 9 },
{ "quantity": 42 }
]
}
Can I use obj.SelectTokens("items..name") and obj.SelectTokens("values..quantity")to correlate "foo" with 9 and "bar" with 42?
My own tests show it to be the case, but without a deeper understanding of the internals, I can't begin to guess what edge cases I'd need to test for.
I've checked code comments, examined the source code (but not gone very far), looked at documentation here, here and here and for any related issues in the GitHub repo here.
The documentation references this article for information on JPath, but it makes no explicit indication either. Though its mention of this JPath $..book[(#.length-1)] returning "the last book in order", at least implies that operations are order-sensitive.
Related
As a CosmosDB (SQL API) user I would like to index all non object or array properties inside of an object.
By default the index in cosmos /* will index every property, our data set is getting extremely large (expensive) and this strategy is no longer optimal. We store our metadata at the root and our customer data wrapped inside of an object property data.
Our platform restricts queries on the data path to be value type properties, this means that for us to index objects and arrays nested under the data path is just slowing down writes and costing RUs to store but never getting used.
I have tried several iterations of index policies but cannot find one that fits. Example:
{
"partitionKey": "f402a704-19bb-4f4d-93e6-801c50280cf6",
"id": "4a7a11e5-00b5-4def-8e80-132a8c083f24",
"data": {
"country": "Belgium",
"employee": 250,
"teammates": [
{ "name": "Jake", "id": 123 ...},
{ "name": "kyle", "id": 3252352 ...}
],
"user": {
"name": "Brian",
"addresses": [{ "city": "Moscow" ...}, { "city": "Moscow" ...}]
}
}
}
In this case I want to only index the root properties as well as /data/employee and /data/country.
Policies like /data/* will not work because it would then index /data/teammates/name ... and so on.
/data/? => assumes data is a value type which it never will be so this doesn't work.
/data/ and /data/*/? and /data/*? are not accepted by cosmos as valid policies.
Additionally I can't simply exclude /data/teammates/ and /data/user/ because what is inside of data is completely dynamic so while that might cover this use case there are several 100k others that it would not.
I have tried many iterations but it seems that options don't work for various reasons, is there a way to support what I am trying to do?
This indexing policy will index the properties you are asking for.
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/partitionKey/?"
},
{
"path": "/data/country/?"
},
{
"path": "/data/employee/?"
}
],
"excludedPaths": [
{
"path": "/*"
}
]
}
We currently have a proof request like this:
{
"name": "pr",
"version": "1.0",
"nonce": "0994650939",
"requested_attributes": {
"attr0_referent": {
"name": "first_name",
"restrictions": [{
"cred_def_id": "credDefIdShareGlobal"
}]
}
},
"requested_predicates": {},
"non_revoked": {}
}
As you can see, on the restricton fields now we have only one restriction. Is it possible to have multiple restrictions on the same attribute (like the example beneath)?
{
"name": "pr",
"version": "1.0",
"nonce": "0994650939",
"requested_attributes": {
"attr0_referent": {
"name": "first_name",
"restrictions": [{
"cred_def_id": "credDefIdShareGlobal1"
}, {
"cred_def_id": "credDefIdShareGlobal2" // <-- Is this possible?
}]
}
},
"requested_predicates": {},
"non_revoked": {}
}
Well, to give some closure to this question, yeah. It works exactly like that.
To give more context, the attribute can be present in different schemas or different credentials and by adding the restrictions as shown they'll be dealt with as an "OR" so, the first one matching will be returned.
If you want to see an test example, I'll advise looking here: https://github.com/eduelias/indy-sdk/blob/MultipleReq/samples/nodejs/src/gettingStarted.js#L470
Is it a violation of the JSON-API spec to allow reverse relationships to be created automatically?
I need to create resources that, when I link A to B in a relationship, automatically links B to A. In this way I can traverse A to find all of its Bs and can find the parent A from a B. However, I don't want to POST/PATCH to 2 relationships to get this right. I want to establish the relationship once.
Now I know that it is an implementation detail as to how the server maintains link/references as well as how the behaviour is established but I want to build the API in such a way that it doesn't violate the spec.
Assuming I have resources Books and Authors. Books have Authors and Authors have Books. The question is, once I relate an Author to a Book, I need the reverse relationship to be created as well. Is it a violation of the spec in any way to assume that this reverse relationship can be automatically created by simply doing one POST to the Books resource's relationship?
By way of example, starting with the book.
{
"data": {
"type": "books", "id": 123, "attributes": ...,
"links": { "self": "/books/123" },
"relationships": {
"self": "/books/123/relationships/authors",
"related": "/books/123/authors"
}
}
}
And the author
{
"data": {
"type": "authors", "id": 456, "attributes": ...,
"links": { "self": "/authors/456" },
"relationships": {
"self": "/authors/456/relationships/books",
"related": "/authors/456/books"
}
}
}
If I establish the link from a book to an author with a POST to /books/123/relationships/authors
{
"data": [{ "data": "authors", "id": "456" }]
}
Do I need to explicitly do the same for the Author 456 as a POST to /authors/456/relationships/books?
{
"data": [{ "data": "books", "id": "123" }]
}
Or can I let the server build the relationship for me so that I can avoid the second POST and just see the automatic reverse relationship at GET /authors/456/relationships/books?
From the perspective of the spec this is only one relationship represented from two different sides. author and book have a many-to-many relationship. This relationship could be represented in author's resource object as well as book's resource object and of course also via there relationship links. Actually it would be a violation of the spirit of the specification if representations wouldn't match. Having one-sided relationships is another story but in that case one side wouldn't know about the relationships at all (e.g. a book is associated with an author but the author model does not know which books are associated with it).
A post to either one side of that relationship creates the relationship between the two records. It shouldn't matter which side is used to create that relationship and if it's created as part of a creation / update to a resource via it's resource object or via a relationship link representing that relationship. The same applies to deletion of that relationship.
Maybe an example would make that even more clear. Let's assume a book is created with a POST to /books?include=author having these payload:
{
"data": {
"type": "books",
"relationships": {
"author": {
"data": {
"type": "authors",
"id": "1"
}
}
}
}
}
The response may look like this:
{
"data": {
"type": "books",
"id": "7",
"relationships": {
"author": {
"data": { "type": "authors", "id": "1" }
}
}
},
"included": [
{
"type": "authors",
"id": "1",
"relationships": {
"books": {
"data": [
{ "type": "books", "id": "7" }
]
}
}
}
]
}
I'm trying to use the AMAZON.LITERAL slot type in my Alexa skill, but when I try building, I see this error:
Build Failed
Slot name "{What}" is used in a sample utterance but not defined in the intent schema. Error code: UndefinedSlotName - Thursday, Apr 12, 2018, 2:08 PM
The slot is named What, and I'm 100% sure it is defined. It builds successfully if I change the slot type to anything except AMAZON.LITERAL.
Here is my entire model:
{
"interactionModel": {
"languageModel": {
"invocationName": "chores",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "Remember",
"slots": [
{
"name": "Who",
"type": "AMAZON.Person"
},
{
"name": "When",
"type": "AMAZON.DATE"
},
{
"name": "What",
"type": "AMAZON.LITERAL"
}
],
"samples": [
"remember {Who} {What} {When}"
]
}
],
"types": []
}
}
}
EDIT:
This is the response I got from Amazon when I submitted the bug:
We are not supporting AMAZON.Literal slot type anymore and we ask
developer to use customer slot type is they have some set of values
but if not then you can use AMAZON.SearchQuery where you will get the
whole query which customer is looking for and same you can use it in
you lambda function.
I faced the same issue. Here's the solution.
You need to define your Sample Utterances as
Remember {Neil | Who} {died | What} {yesterday | When}
Amazon made it mandatory to provide the example inputs along with your Slot names as AMAZON.LITERAL can take in a wide variety of values.
For more information, refer here.
add some sample utterances in below format and it should work:
remember {Jack|Who} {bring fruits|What} {tomorrow|When}
remember {Mark|Who} {pay bills|What} {today|When}
Using node JSONPath, how can I get the parent node name from child node value
{
"store": {
"book": [
{
"id":"1",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"id":"2",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
]
}
}
I use this expression to identify the child node based on value, I want to use this child node to find the parent node
$.[?(#.id =="1")]
You do not specify which implementation of JSON Path, but with both Gatling (Scala) and JayWay (Java) you can use nested filters to filter by children while returning the parent, grandparent or whatever. Here is a sample:
With this JSON:
{
"a": {
"b": {
"c": {
"d": {
"e": "foo"
}
},
"something": "bar"
}
}
}
And this path:
$.a.b[?(#.c[?(#.d[?(#.e == "foo")])])].something
Returns:
[ "bar" ]
I am able to retrieve b by using expressions to get to lower nodes as the filter.
Some other implementations error out on these expressions.
Unfortunately, JSONpath does not support search by parameters in the contents of a child object:
http://goessner.net/articles/JsonPath/
With JayWay it works but the query provided by Jayson is wrong, because if you change the value to "foo2" it will still return "bar".
This can be tested on http://jsonpath.herokuapp.com/.
Query:
$.a.b[?(#.c.d.e=="foo")].something
Returns:
["bar"]
Query:
$.a.b[?(#.c.d.e=="foo2")].something
Returns:
[]