Open o0x2a opened 8 years ago
Adding a parent reference would require path tracing, which is fairly complicated to do especially through pipes and other transforms that reset the object to something fairly unrelated. I have been working on this for a port of the Java implementation and if I have successful experiments will push this back towards the spec. The issue is that such as small thing as this one function, completely makes implementation much more complicated.
In my version, I trace the query and have a full trace and the object at each step, so the trace acts as a way to get the path of any found node, but also since you have the trace, you can go upwards in a trace to find a parent. (assuming ..
deep pathing traces each level it went through) ... The objects themselves typically have no upwards pointers to parents, so the engine has to know and it can via tracing.
How about storing reference to parent object in each child node as we navigate from root to each child? By storing the reference to the parent node we may not require path tracing.
That is basically what tracing would do, but also crosses over pipes, collapsing arrays, and other steps.
Outside of tracing, yes parent node references could be kept from each point where you stop projection (i.e. pipe) so you can reach back up to that point. Basically a map from child->parent for each step of the tree.
One approach could be to store a reference to the original source data structure in a special variable (I was thinking $
might be a suitable identifier for this).
For example given the following input:
{
"a": 5,
"b": [
{"c": 6},
{"c": 7},
{"c": 8}
]
}
It's currently impossible to generate something like this:
[
{"a": 5, "b": 6},
{"a": 5, "b": 7},
{"a": 5, "b": 8}
]
With $
representing a reference to the source input, you could generate the above using the following expression:
b[].{a:$.a,b:c}
It might make sense to reset $
whenever you pipe an expression to another, given you are free to capture $
or a subtree of $
in the prior expression that is piped in.
I don't think this would be too difficult to implement - each reference to $
is another query that just needs to be evaluated from the source input.
Fyi I'm unable to use JMESPath for a product I'm building - my requirements can only be met if I have '$' functionality.
Using Symbol couls also be an option. Don't know how much extra complication that might lead to.
Path tracing might not be needed if we can put the parent object in the symbol. Something like this:
var parentSymbol = Symbol("parent");
obj[parentSymbol] = parent;
I've used this successfully in plain javascript.
+1, possibility of access to parent object will be very useful in many cases
I want to propose @..
for parent access. Is it collide with any existing syntax?
Hello! Anything on this, please?
@barbu110 It seem jmespath just set in stone. No new feature will be added and become standardized as json. Currently now I lose hope in jmespath to add new feature and am working on new parser of my own. But I still don't have good syntax for parent accessor, really harder than I thought
I use a method where preprocess and set a parent Symbol and then use a proxy as data input. Whenever the parent property comes up, the proxy then delegates to the symbol. This approch requires no changes to the library.
@Allam76 Can you post an example of how you handled that?
I added support for $
to access the root object in my fork of jmespath.js.
The example given above, with b[].{a:$.a,b:c}
works, as you can see here:
https://codesandbox.io/s/upbeat-elgamal-xxz7s?fontsize=14&hidenavigation=1&theme=dark
I added $
as a new token (TOK_ROOT
) to the lexer and parser, as you can see in this commit: https://github.com/daz-is/jmespath.js/commit/0d28f249d7b3fa6a2bafcc12227ef17f27762b01
Sure: jsonata parent proposal both my solution and native implementation
If this is something you are looking to do, take a look at object-scan as an alternative to jmespath. The filter functionality is more limited, but it does provide a lot of search context
Disclaimer: I'm the author
As a user, I want to use pipe or a modifier or a function to access the parent object.
or