ajson
ajson copied to clipboard
Add filter for values
Hello! It would be great if there was a possibility of filtering objects by value as it's for arrays values. F.e.:
-
Array values Here is the data:
{"data": ["b"]}
And the filter:$.data[?(@ == ‘b’)]
will bring the node. Works with arrays fine! -
Object values Here is the data:
{ "price": 1}
And I'd like to have a filter like this:$.price?(@ == 1)
which would return the node
Hello! Thanks, I think it could be useful. Will try to implement it in the next release.
This is a very useful feature, still in roadmap to be included in a future release?
I think so. Will implement it in the version v1.X.X
.
I started looking at this, but it is not clear how this should be implemented without changing how the current filtering works so maybe allowing this feature but not changing the current implementation.
I encounter this issue:
ParseJSONPath
already transform $.data[?(@ == ‘b’)]
into []string{"$","data","?(@ == ‘b’)"}
which means that $.data[?(@ == ‘b’)]
and $.data?(@ == ‘b’)
will return the same slice which means that anyone that is using ApplyJSONPath
directly is passing only ?(@ == ‘b’)
.
Ideas:
-
I thought the expression output could be different e.g
[?(@ == ‘b’)]
and?(@ == ‘b’)
unfortunately this will break any implementation that is currently callingApplyJSONPath
and passing only expression?(@ == ‘b’)
. they will need to change all expressions to include[]
in order to have the current filter -
Another idea although not present anywhere could be use
{}
instead[]
when the filtering/exp should be applied to the current node e.g$.data[?(@ == ‘b’)]
and$.price{?(@ == 1)}
. In order to not break the currentApplyJSONPath
functionality the commands could be structs instead of strings with a flag that tells if should be applied to the current node andApplyJSONPath
can continue to get[]string
and create[]Command
with the flag that tells that filter is in inheritors.
e.g(2) for:
{
"type": "book",
"id": "A1234",
"author": {
"id": "AA123",
"name": "Foo"
}
"notes": [
{
"id": "N1",
"title": "Some title 1",
"note": "Nice"
},
{
"id": "N2",
"title": "Some title 2",
"note": "Very Nice"
}
]
}
// $.notes[?(@.id=="N1")]
{
"id": "N1",
"title": "Some title 1",
"note": "Nice"
}
// ${?(@.type=="book")}.author
{
"id": "AA123",
"name": "Foo"
}
What do you think about this?
Thanks for the suggestions! Unfortunately, I can't implement {...}
filter as it is not in the specification, but you can try to add this suggestion to the ietf JSONPath (draft). If it passes, I will implement it :-)
The simplest way, how to implement it without the new filter - to add a new function or operator.
I will try to implement some operators from the https://www.postgresql.org/docs/9.5/functions-json.html , like:
Operator | Operand Type | Description | Example |
---|---|---|---|
@> |
object | Does the left JSON value contain the right JSON path/value entries at the top level? | '{"a":1, "b":2}' @> '{"b":2}' |
<@ |
object | Are the left JSON path/value entries contained at the top level within the right JSON value? | '{"b":2}' <@ '{"a":1, "b":2}' |
So it will be available to use requests like $..[?(@ @> {"b":2})]
, but as you can see @
here looks a little out of place here. I probably will change this symbol.
@aaroalan, I created a draft for V1 milestone: #42. The whole project will be rewritten.