12

I am trying to build a single JSONPath query which will test existence of two or more paths.

Let's consider the following sample document:

{
          "firstName": "John",
          "lastName" : "doe",
          "age"      : 26,
          "address"  : {
            "streetAddress": "naist street",
            "city"         : "Nara",
            "postalCode"   : "630-0192"
          },
          "phoneNumbers": [
            {
              "type"  : "iPhone",
              "number": "0123-4567-8888"
            },
            {
              "type"  : "home",
              "number": "0123-4567-8910"
            }
          ]
}

So far I have found:

$..[firstName,lastName,type]

And get all of these elements from the entire document.

But, what I need is to check two different paths, e.g.:

 $.firstName 
 $.address.city

Can this be done with a single JSONPath query? I cannot write anything like:

$.[firstName,address.city]

With XML and XPath I could write:

/person/firstname | /person/address/city

and get a union of all matching XML elements.

Can I do the same with JSONPath?

2 Answers 2

7

I think the closest you can come in the original JSONPath is using recursive descent and union, i.e.

$..['firstName','city']

The Goessner implementation will return

[
   "John",
   "Nara"
]

kubernetes JSONPath supports an extension to the union operator, allowing

[‘metadata.name’, ‘status.capacity’]

where name and capacity are members of metadata and status.

JSONMatch, which is a variant of JSONPath, and originally based on the Kubernetes JSONPath parser, supports union of completely separate paths, e.g.

[employee[5].name, company.name, wageTiers[compensation > 10000]]

JSONMatch is available in go and I believe javascript also.

A handful of JSONPath implementations support bracket notation with two literals separated by dot and bracket notation with two literals separated by dot without quotes.

The jsoncons C++ library (since 0.161.0) supports JSONPath union of completely separate paths with the notation

$..['firstName',@.address.city]
Sign up to request clarification or add additional context in comments.

3 Comments

Yes, I have also come to this point, but I wonder if distinct paths can be queried by a single query.
As the author of a C++ JsonPath implementation, I would say the answer is no, with a strict interpretation of the spec, to the extent that it can be called a "spec". The question has come up before, and it may be possible to imagine an extension. But I don't know of any existing implementations that has one.
Thanks, so, this might be an answer to my question.
0

This answer is not 100% an answer to the question as it assumes nodejs/javascript. Since it describes how we overcame the limitations of JSONPath it is my hope that it might help others.


We had a similar requirement. However we needed to look for hundreds of different paths and do processing for them and performance was an actual issue. We then replaced JSONPath with object-scan. It's a bit more limited, but has some advantages when you need to do data processing.

Here is how you could solve your question (note that you could separate the compile and run part to make subsequent executions more performant):

// const objectScan = require('object-scan');

const data = { firstName: 'John', lastName: 'doe', age: 26, address: { streetAddress: 'naist street', city: 'Nara', postalCode: '630-0192' }, phoneNumbers: [{ type: 'iPhone', number: '0123-4567-8888' }, { type: 'home', number: '0123-4567-8910' }] };

const r = objectScan(['firstName', 'address.city'], { rtn: 'count' })(data);

console.log(r);
// => 2
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Disclaimer: I'm the author of object-scan

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.