JsonPath AND Operator on Array - jsonpath

I have an array in JSON and I would like to apply two filters to it like so:
$._embedded.values[0]._embedded.data[?(#.var1='value1' && #.var2='value2')]
I need to select only those elements from the array that satisfies the AND operation. However, in practice this doesn't appear to work.
Is it possible to do this or must I perform a two step action to extract one set then filter again to get my final results?

The Jayway implementation supports inlined AND and OR criteria.
$..book[?(#.price==8.99 && #.category=='fiction')]
[
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}
]
Try it out and compare different implementations here http://jsonpath.herokuapp.com/

below is an example showing JSON path with AND and OR criteria:
Get all books with price less than 10 and of 'fiction' category
$..book[?(#.price<10 && #.category=='fiction')]
Get all books with price less than 10 or any book of 'fiction' category
$..book[?(#.price<10 || #.category=='fiction')]
You can also try mixing up AND and Or criteria:
Get books of 'Herman Melville' with with price less than 10 or his book of 'fiction' category
$..book[?(#.author=='Herman Melville' && (#.price<10 || #.category=='fiction'))]

As far as I know AND / OR are not supported yet. But you can get relatively close with this [,] array. But even this made me wonder when I tested it. There's some strange behaviour. I took an example JSON string from the Jayway JsonPath Evaluator and put it into JsonPath Expression Tester (because it didn't work with Jayway when I tried).
So the JSON I've tested with the curiousconcept version is:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
And the expression:
$..book[?(#.price==8.99),?(#.category=='fiction')]
which results in:
[
{
"category":"fiction",
"author":"Herman Melville",
"title":"Moby Dick",
"isbn":"0-553-21311-3",
"price":8.99
}
]
what seems to be perfect. (take the price 8.99 AND category 'fiction'... perfect!)
BUT: change it to:
$..book[?(#.category=='fiction'),?(#.price==8.99)]
then the output is:
[
]
It seems to me that [,] is not well implemented in Jayway JsonPath Tester as well as curiousconcept.com expression tester.
But from what I know they're working on an (real) implementation of AND and or (issue27 here at google code).
Hope this clarifies at least something!

Related

Can't get the desired properties via JsonPath evaluate method

I have a json schema that marks special properties in need of processing and I want to query those via JsonPath.Evaluate.
Here's a part of the schema to illustrate the issue
{
"type": "object",
"properties": {
"period": {
"description": "The period in which the rule applies",
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time"
},
"end": {
"type": "string",
"format": "date-time"
}
},
"required": [
"start"
],
"x-updateIndicatorProperties": [
"start"
]
},
"productType": {
"type": "string"
},
"x-updateIndicatorProperties": [
"productType"
]
}
}
I want to get the the JsonPath of the "x-updateIndicatorProperties" properties, so that I can then query the actual properties to process.
For this example, the expected result would be
[
"$['properties']['x-updateIndicatorProperties']",
"$['properties']['period']['x-updateIndicatorProperties']"
]
I've been trying for a while to get a JsonPath expression that would query these properties.
Currently I'm just iterating all properties and filter them manually :
"$..*"
I've also tried using :
$..['x-updateIndicatorProperties']
This works. But it returns a lot of duplicates. For the example above, I get 5 results instead of the expected 2. Can be demonstrated here : https://json-everything.net/json-path
Assuming I can't influence the schema itself, only the code that traverses it,
can anybody help with an expression to get the expected results or any other way to achieve the same outcome?
The stack is JsonPath 0.2.0, .net 6 and system.text.json.
This was a bug in the library when parsing paths that use a recursive descent (..) into a quoted-property-name selector (['foo']). So it would happen for any path in the form $..['foo'].
I've fixed the issue and released version 0.2.1.

How to handle Polymorphic endpoints on Pact?

I have an app where I can search for Books and Movies. These 2 entities have different properties, so their JSON structures are different.
I also have a GET /favorites endpoint which should return both Books and Movies.
GET /favorites
{
"favorites": [
{
"type": "book",
"title": "Foo",
"author": "John"
},
{
"type": "movie",
"name": "Bar",
"producers": [
{
"firstName": "Mary"
}
]
}
]
}
I searched for for docs on this case but I can't find anything. How can I write a Pact contract for this use case?
I would write two separate test cases for this, and use Provider States to differentiate the two payloads.
For example:
When there are books
When there are movies
Or something to that effect. See [1] for related background on this.
[1] https://docs.pact.io/faq#why-is-there-no-support-for-specifying-optional-attributes

Get vertices with a simpler format

Is there a way to get a list of vertices with a simpler format?
Currently, the following query:
g.V().has(label, 'Quantity').has('text', '627 km');
returns an object like this:
{
"id": 42545168,
"label": "Quantity",
"type": "vertex",
"properties": {
"sentence": [
{
"id": "pkbgi-pbw28-745",
"value": "null"
}
],
"updated_text": [
{
"id": "pk9vm-pbw28-5j9",
"value": "627 km"
}
],[...]
And when I get a list of edges it is formatted in a simpler format:
g.E().has(label, 'locatedAt').has('out_entity_id','41573-41579');
returns:
{
"id": "ozfnt-ip8o-2mtx-g8vs",
"label": "locatedAt",
"type": "edge",
"inVLabel": "Location",
"outVLabel": "Location",
"inV": 758008,
"outV": 872520,
"properties": {
"sentence": "Bolloré is a corporation (société anonyme) with a Board of Directors whose registered offi ce is located at Odet, 29500 Ergué-Gabéric in France.",
"in_entity_id": "41544-41548",
"score": "0.795793",
"out_entity_id": "41573-41579"
}
}
How so?
Is there a way to get vertices formatted this way?
My advice is to rather than have your query return the whole vertex, return the specific properties that you are interested in. For example the vertex ID or some selected properties that you are interested in or a valueMap. Otherwise what you will get back is essentially everything. This is really the same as in SQL trying to not do a "select *" but selecting only what you really care about.
Edited to add an example that returns the IDs of matching vertices.
g.V().has(label, 'Quantity').has('text', '627 km').id().fold()
Will yield a result that looks like this
{"requestId":"73f40519-87c8-4037-a9fc-41be82b3b227","status":{"message":"","code":200,"attributes":{}},"result":{"data":[[20608,28920,32912,106744,123080,135200,139296,143464,143488,143560,151584,155688,155752,159784,188520,254016,282688,286968,311360,323832,348408,4344,835648,8336,1343616,12352]],"meta":{}}}

Dictionary object type error

I've updated my project to Swift 3 from 2.3 and I'm getting an interesting object error for dictionaries. I've tried rewriting this literal in a couple different ways to no luck and looked for answers but none so far posted for 3.0...
let jsonRequest: [String: AnyObject] = [
"requests": [
"image": [
"content": imageData
],
"features": [
[
"type": "LABEL_DETECTION",
"maxResults": 10
],
[
"type":"IMAGE_PROPERTIES",
"maxResults": 1
]
]
]
]
Error displayed:
"Contextual type 'AnyObject' cannot be used with dictionary literal"
Can anyone explain to me what needs to be changed? Thanks!

correct GeoJSON format. map visualization

First things first: is this data in proper GeoJSON format?
According to the definition of GeoJSON data, as you can see by the MultiPoint & coordinates, I think it is.
It looks like this:
{
"lang": {
"code": "en",
"conf": 1.0
},
"group": "JobServe",
"description": "Work with the data science team to build new products and integrate analytics\ninto existing workflows. Leverage big data solutions, advanced statistical\nmethods, and web apps. Coordinate with domain experts, IT operations, and\ndevelopers. Present to clients.\n\n * Coordinate the workflow of the data science team\n * Join a team of experts in big data, advanced analytics, and visualizat...",
"title": "Data Science Team Lead",
"url": "http://www.jobserve.com/us/en/search-jobs-in-Columbia,-Maryland,-USA/DATA-SCIENCE-TEAM-LEAD-99739A4618F8894B/",
"geo": {
"type": "MultiPoint",
"coordinates": [
[
-76.8582049,
39.2156213
]
]
},
"tags": [
"Job Board"
],
"spider": "jobserveNa",
"employmentType": [
"Unspecified"
],
"lastSeen": "2015-05-13T01:21:07.240000",
"jobLocation": [
"Columbia, Maryland, United States of America"
],
"identifier": "99739A4618F8894B",
"hiringOrganization": [
"Customer Relation Market Research Company"
],
"firstSeen": "2015-05-13T01:21:07+00:00"
},
I want to visualize this as a "zoomable",viz. interactive, map, as in the examples on the d3js website.
I'm trying to use a tool called mapshaper.org to see an initial visualization of the data in map form, but when I load it up, nothing happens.
To me this doesn't make sense because, according to their website, one can simply
Drag and drop or select a file to import.
Shapefile, GeoJSON and TopoJSON files and Zip archives are supported.
However, in my case it is not working.
Does anyone have any intuition as to what might be going wrong, or a suggestion as to a tool comparable to create a zoomable map out of GeoJSON data?
According to the definition of GeoJSON data, I have what I think constitutes data in that format
Well, you don't have a proper GeoJSON object. Just compare what you've got against the example you've linked. It doesn't even come close. That's why mapshaper doesn't know what to do with the JSON you load into it.
A GeoJSON object with the type "FeatureCollection" is a feature collection object. An object of type "FeatureCollection" must have a member with the name "features". The value corresponding to "features" is an array. Each element in the array is a feature object as defined above.
A feature collection looks like this:
{
"type": "FeatureCollection",
"features": [
// Array of features
]
}
http://geojson.org/geojson-spec.html#feature-collection-objects
A GeoJSON object with the type "Feature" is a feature object. A feature object must have a member with the name "geometry". The value of the geometry member is a geometry object as defined above or a JSON null value. A feature object must have a member with the name "properties". The value of the properties member is an object (any JSON object or a JSON null value). If a feature has a commonly used identifier, that identifier should be included as a member of the feature object with the name "id".
A feature looks like this:
{
"id": "Foo",
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, 0]
},
"properties": {
"label": "My Foo"
}
}
http://geojson.org/geojson-spec.html#feature-objects
Here are examples of the different geometry objects a feature can support: http://geojson.org/geojson-spec.html#appendix-a-geometry-examples
Put those two together, it would look like this:
{
"type": "FeatureCollection",
"features": [{
"id": "Foo",
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, 0]
},
"properties": {
"label": "My Foo"
}
},{
"id": "Bar",
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[100.0, 0.0],
[101.0, 1.0]
]
},
"properties": {
"label": "My Bar"
}
}]
}
That really doesn't look like the JSON you've posted. You'll need to convert that to proper GeoJSON somehow via a custom script or manually. It's a format i've never seen before, sorry to say.

Resources