Skip to content

Understanding difference between "@property=='<property_key>" and "@.<property_key>" #109

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sankalpn opened this issue Nov 21, 2019 · 1 comment

Comments

@sankalpn
Copy link

While trying out different filters, I noticed the following:

  1. Filtering with @Property works intuitively.
    JSONPath({ path: '$.[?(@property === "appName" && @ === "app1")]^', json: { "version": 1, "appName": "app1" }, wrap: false });
    The json passes filter and gets returned
    {"version":1,"appName":"app1"}
  2. The same thing with @.<property_name> filters out above json.
    JSONPath({ path: '$.[?(@.appName === "app1")]^', json: { "version": 1, "appName": "app1" }, wrap: false });
    This returns
    undefined

Is this behaviour expected? If yes, can we add a couple of more examples to documentation?

@brettz9
Copy link
Collaborator

brettz9 commented Apr 9, 2020

In your second example:

JSONPath({ path: '$.[?(@.appName === "app1")]^', json: { "version": 1, "appName": "app1" }, wrap: false });

...you wouldn't want the parent selector (^), as that would be looking above root (since that filter is on an object, and that object happens to be root.

But even without the parent selector, the expression still doesn't match.

I think the problematic aspect here is that filters apply to children, and there is thus no apparent way to use the object-selectors in a way that matches root (though as per your first example, and as per #118, one can use property selectors along with the parent selector to match root because property selectors are looking at children not at the containing parent object).

Note that this gets the object (albeit in an array):

    const result = jsonpath({
        path: '$.[?(@.appName === "app1")]',
        json: {a: {version: 1, appName: 'app1'}}, wrap: false});
    assert.deepEqual(result, [{version: 1, appName: 'app1'}]);

That works because the object is no longer at root, and the comparison is on the children.

So I think the real issue here is that we need a type of filter which checks the targeted item directly rather than its children (or at least so that we might allow reaching above root in the case of filters, e.g., $.^[?(@.appName === "app1")]). (That currently also gets a bad error, this._trace(...).filter is not a function.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants