user2459396
user2459396

Reputation: 95

MarkLogic Java API to search for a specific path in JSON document

I am using MarkLogic Java API to search JSON documents stored in MarkLogic 9 collection. My JSON is structured as below

{
  "time": "2021-02-09T11:09:53",
  "payload": {
    "a": "v1",
    "b": "v2",
    "c": [
      {
        "d": {
          "a": "v1",
          "b": "v2"
        }
      }
    ]
  }
}

I am trying to search for /payload/a=v1 and /payload/b=v2 but the search also returns all those documents where /payload/c/d/a=v1 and /payload/c/d/b=v2

Here is my Java code

StructuredQueryBuilder sqb = queryManager.newStructuredQueryBuilder();

List<StructuredQueryDefinition> list = new ArrayList<>();

list.add(sqb.collection("collectionName"));

StructuredQueryDefinition a = sqb.value(sqb.jsonProperty("a"), "v1");
StructuredQueryDefinition b = sqb.value(sqb.jsonProperty("b"), "v2");

list.add(sqb.and(sqb.containerQuery(sqb.jsonProperty("payload"), sqb.and(a, b)))));

StructuredQueryDefinition definition = sqb.and(list.toArray(new StructuredQueryDefinition[list.size()]));
DocumentPage page = docManager.search(definition, 1L);

Any help would be well appreciated.

Thanks, AK

Upvotes: 1

Views: 148

Answers (1)

ehennum
ehennum

Reputation: 7335

One approach would be to use a TDE to project payload/(a|b) into a two-column view.

In the Java API, the RowManager can then match documents by criteria for those columns. Use the joinDoc() operation to join and return the full content of the documents.

An alternative would be to define a path range index on payload/a, which eliminates the false positives under payload/c/d/a. The concern about range indexes is that they are heavyweight (because they are memory mapped, they use resource whether in use or not) and provide a less general solution.

Hoping that helps,

Upvotes: 2

Related Questions