Search code examples
ruby-on-railsruby-on-rails-3elasticsearchelasticsearch-rails

How to search multiple generations in Elasticsearch


Elasticsearch's article outlines how to find objects based on a search through one generation: https://www.elastic.co/guide/en/elasticsearch/guide/current/grandparents.html

GET /company/country/_search
{
  "query": {
    "has_child": {
      "type": "branch",
      "query": {
        "has_child": {
          "type": "employee",
          "query": {
            "match": {
              "hobby": "hiking"
            }
          }
        }
      }
    }
  }
}

What if I want to also want to query the branch for the name starting with "liverpool"? How do you modify this search to find that? I keep getting format errors and I can't seem to find information about how nest the queries online.

I've already tried this (it doesn't work):

GET /company/country/_search
{
  "query": {
    "has_child": {
      "type": "branch",
      "query": {
        "has_child": {
          "type": "employee",
          "query": {
            "match": {
              "hobby": "hiking"
            }
          }
        },
        "match": {
          "name": "london"
        }
      }
    }
  }
}

I got an error that said the query was malformed.

I tried bool, but it doesn't work either; I can't use has_child with a bool.


Solution

  • I was able to make it work with a bool query.

    If I'm understanding your question correctly, this should do what you want:

    POST /company/country/_search
    {
       "query": {
          "has_child": {
             "type": "branch",
             "query": {
                "bool": {
                   "must": [
                      {
                         "has_child": {
                            "type": "employee",
                            "query": {
                               "match": {
                                  "hobby": "hiking"
                               }
                            }
                         }
                      },
                      {
                         "match": {
                            "name": "liverpool"
                         }
                      }
                   ]
                }
             }
          }
       }
    }
    

    If you want the query to be an "OR" instead of an "AND", use "should" instead of "must".

    Here is some code I set up to play around with the problem:

    http://sense.qbox.io/gist/cf4babbbd25a3b7a26f3ea9ce9c1b686e37dbcb9