2

I have mapped data into this schema:

curl -X PUT "localhost:9200/data?pretty" -H 'Content-Type: application/json' -d 
'{
   "settings":{
      "number_of_shards":"1",
      "number_of_replicas":"1"
   },
   "mappings":{
      "properties":{
         "routines":{
            "type":"nested",
            "properties":{
               "title":{
                  "type":"text"
               },
               "sources":{
                  "type":"keyword"
               },
               "flags":{
                  "type":"keyword",
                  "null_value":"NULL"
               },
               "steps":{
                  "type":"nested",
                  "properties":{
                     "time":{
                        "type":"keyword"
                     },
                     "products":{
                        "type":"nested",
                        "properties":{
                           "name":{
                              "type":"text"
                           },
                           "link":{
                              "type":"keyword",
                              "null_value":"NULL"
                           },
                           "type":{
                              "type":"keyword",
                              "null_value":"NULL"
                           },
                           "ingredients":{
                              "type":"keyword",
                              "null_value":"NULL"
                           },
                           "flags":{
                              "type":"keyword",
                              "null_value":"NULL"
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}'

Now, I am trying to search two fields data.title and data.steps.products.name with this query:

curl -X GET "localhost:9200/data/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "data",
            "query": {
              "nested": {
                "path": "steps",
                "query": {
                  "nested": {
                    "path": "products",
                    "query": {
                      "multi_match": {
                        "query": "XXX",
                        "fields": [
                          "name"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        {"multi_match": {
                "query": "XXX",
                "fields": [
                  "data.title"
                ]
              }
            }
      ]
    }
  }
}'

It throws error that it failed to find path under step:

{
  "error" : {
    "root_cause" : [
      {
        "type" : "query_shard_exception",
        "reason" : "failed to create query: [nested] failed to find nested object under path [steps]",
        "index_uuid" : "SjQgt4BHStC_APsMnZk8BQ",
        "index" : "data"
      }
    ],
    "type" : "search_phase_execution_exception",
    "reason" : "all shards failed",
    "phase" : "query",
    "grouped" : true,
    "failed_shards" : [
      {
        "shard" : 0,
        "index" : "data",
        "node" : "L1azdi09QxanYGnP-y0xbQ",
        "reason" : {
          "type" : "query_shard_exception",
          "reason" : "failed to create query: [nested] failed to find nested object under path [steps]",
          "index_uuid" : "SjQgt4BHStC_APsMnZk8BQ",
          "index" : "data",
          "caused_by" : {
            "type" : "illegal_state_exception",
            "reason" : "[nested] failed to find nested object under path [steps]"
          }
        }
      }
    ]
  },
  "status" : 400
}

Could you help to find an error with mapping/query?

UPDATE:

My json data: https://jsonkeeper.com/b/PSVS

1 Answer 1

4

Have a look at the Elastic documentation for multi-level nested queries.

What you forgot in your query is the full path of the nested object in each sub-level nested query. (also, you used a data field not existing in the mapping, while you wanted to have routines instead)

So your query would look like

curl -X GET "localhost:9200/data/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "query": {
    "bool": {
      "should": [
        {
          "nested": {
            "path": "routines",
            "query": {
              "nested": {
                "path": "routines.steps",
                "query": {
                  "nested": {
                    "path": "routines.steps.products",
                    "query": {
                      "multi_match": {
                        "query": "XXX",
                        "fields": [
                          "routines.steps.products.name"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        {"multi_match": {
                "query": "XXX",
                "fields": [
                  "routines.title"
                ]
              }
            }
      ]
    }
  }
}'

Anyhow, please reconsider whether it is a good idea to have multi-level nested fields in the first place, as they have a significant impact on performance. E.g., would having an index for routines, maybe with a data identifier, make sense?

Edit: added the full path to the multi-matched field of the first should block

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks a lot @glenacota! For now it doesn't have to be the most performant but I will look into it! I still have an issue with this query. It returns no hits... I've updated the question with json document data. Could you help me? Maybe I did wrong mapping?
hi, yes, your mapping is not matching your data. In your mapping, you defined steps as a sub-field of the routines root field, but in your data there's no routines field and steps is the root.
sorry, the file saved under the URL didn't save properly. Here is the good data: jsonkeeper.com/b/PSVS
try to add the full path to the (routines.steps.products.)name field of the multi_match query of the first should block

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.