Mehul
Mehul

Reputation: 178

How to search in MarkLogic JSON for a key's value at a particular path in the file?

I have a few JSON documents of a particular format in my database. There is a key that occurs at two places in the document. I want to write a search query where I can search for the value at only the 2nd occurrence. For a clearer picture please refer to the below sample created.

I tried cts.jsonPropertyScopeQuery("c1",cts.trueQuery()) but it is not path specified. I also tried cts.jsonPropertyScopeQuery("c1", "e/c1").

 {
    "a": "aa",
    "b": "bb",
    "c": {
        "c1": "cc",
        "c2": "ccc"
    },
    "d": "dd",
    "e": {
        "c1": "xx"
    }
}

I expect the query to fetch all values of c1 under e from all documents and put them in an array for further processing.

Upvotes: 2

Views: 437

Answers (3)

grtjn
grtjn

Reputation: 20414

I concur with Dave, if you are looking for values anyhow, use cts.values rather than cts.search.

The path range query that Kim suggests is good for accurate searching, but the scope query should work too, and has the advantage of not needing pre-defined range indexes. The way to use it is as follows:

cts.jsonPropertyScopeQuery("e",
  cts.jsonPropertyScopeQuery("c1",
    cts.trueQuery()))

As explained in the Usage Notes of the docs on cts.jsonPropertyScopeQuery, scope queries do require positions to be enabled. It is recommended to enable both word position and element word position indexes.

One important difference between above scope queries, and a path index on e/c1 is that with the path index the c1 must be a child of e, while the scope query only checks for descendants. The scope query is essentially the equivalent of the path e//c1.

HTH!

Upvotes: 1

Dave Cassel
Dave Cassel

Reputation: 8422

Since you want to retrieve the list of values, you want to set an index. If you wanted all c1 values, you'd use a range index, but since you only want some of them, you'll need a path range index. After you have that set up, you can use cts.values.

Further details: Using Range Indexes for Value Lexicons.

Upvotes: 1

kcoleman
kcoleman

Reputation: 666

If the path is known, consider defining a path range index on the specific path and using a cts.pathRangeQuery or cts.values, depending on your goal.

For example, define a path range index on /e/c1 (or e/c1 if it needs to be relative), and then use cts.values on that index to fetch all values:

cts.values(cts.pathReference("e/c1"))

Similarly, you can use a cts.pathRangeQuery if you want to search for documents containing a specific value, rather than a list of all the values:

cts.search(cts.pathRangeQuery("e/c1","=","xx"))

Further details: Understanding Path Range Indexes.

Upvotes: 2

Related Questions