Sagi Mann
Sagi Mann

Reputation: 3610

how to use Elastic Search nested queries by object key instead of object property

Following the Elastic Search example in this article for a nested query, I noticed that it assumes the nested objects are inside an ARRAY and that queries are based on some object PROPERTY:

{
    nested_objects: [   <== array
         { name: "x", value: 123 },
         { name: "y", value: 456 }  <== "name" property searchable
    ]
}

But what if I want nested objects to be arranged in key-value structure that gets updated with new objects, and I want to search by the KEY? example:

{
    nested_objects: {   <== key-value, not array
         "x": { value: 123 },
         "y": { value: 456 }  <== how can I search by "x" and "y" keys?
         "..."  <=== more arbitrary keys are added now and then
    ]
}

Thank you!

Upvotes: 1

Views: 1560

Answers (2)

Sagi Mann
Sagi Mann

Reputation: 3610

Ok, so my final solution after some ES insights is as follows: 1. The fact that my object keys "x", "y", ... are arbitrary causes a mess in my index mapping. So generally speaking, it's not a good ES practice to plan this kind of structure... So for the sake of mappings, I resort to the structure described in the "Weighted tags" article:

{ "name":"x", "value":123 },
{ "name":"y", "value":456 },
...
  1. This means that, when it's time to update the value of the sub-object named "x", I'm having a harder (and slower) time finding it: I first need to query the entire top-level object, traverse the sub objects until I find one named "x" and then update its value. Then I update the entire sub-object array back into ES.

  2. The above approach also causes concurrency issues in case I have multiple processes updating the same index. ES has optimistic locking I can use to retry when needed, or, I can queue updates and handle them serially

Upvotes: 0

Val
Val

Reputation: 217314

You can try to do this using the query_string query, like this:

GET my_index/_search 
{
  "query": {
    "query_string": {
      "query":"nested_objects.\\*.value:123"
    }
  }
}

It will try to match the value field of any sub-field of nested_objects.

Upvotes: 1

Related Questions