2

I'm working on setting up an Elasticsearch index and would like it to behave (return results) a certain way. I've got a parent / child relationship set up.

curl -XPUT 'http://127.0.0.1:9200/parent/' -d '
{
  "mappings": {
    "parent": {},
    "child": {
      "_parent": {
        "type": "parent" 
      }
    }
  }
} '

And I've populated it with some "parent" documents, and a bunch of "child" documents whose parent is correctly set.

When I search the content using with a normal search query I, of course, get back all documents that match. Parent and child documents but no tie between then. If I search the content using the has_child filter it correctly searches the child documents and returns to me the parent document that matches:

curl -XGET 'http://127.0.0.1:9200/parent/_search' -d '
{
  "query": {
    "has_child": {
      "type":         "child",
      "query": {
       "match": {
        "detail": "Stuff I Want To Match"
      }
    }
  }
} 
}'

The thing is, I want to search the children and get back the parent AND the children in a single document. Is there a way to accomplish this? Is the parent-child relationship the wrong one?

Dave Holland
  • 197
  • 7
  • By way of update I was just looking at nested objects and I seem to run into the same issue with those as well, unless I am mistaken. – Dave Holland Aug 08 '14 at 19:20
  • 2
    Nope, you can't. You get back the type of object that you search. Period. If you use nested objects, you can search for a top-level doc with nested properties matching a nested query; you will get back top-level docs including *all* of the nested docs, not just the one that matched. You want to get back the parent doc type with a single, nested child? You'll have to index the parent+child document for every child the parent has. Elasticsearch doesn't do 'joins'. – GlenRSmith Aug 08 '14 at 22:05
  • Glen - You're totally right. I was trying to avoid the need to reindex the entire document every time I add a child / nested document to it... Which is why the parent/child relationship at first seemed attractive. I'm going to use nested documents. – Dave Holland Aug 08 '14 at 22:41

2 Answers2

1

I want to do the same thing recently. And I figured out to print out the parent document and child documents into one elasticsearch result. But ideally it may be able to put parent and child into one json block.

Here is what I can do for now to get all the matching parent and child documents together.

curl -XGET 'http://127.0.0.1:9200/indexname/parent,child/_search' -d '
{
   "query": {
      "bool": {
         "should": [
            {
               "has_child": {
                  "type": "child",
                  "query": {
                     "match": {
                        "detail": "Stuff I Want To Match"
                     }
                  }
               }
            },
            {
               "match": {
                  "detail": "Stuff I Want To Match"
               }
            }
         ]
      }
   }
}'

Let's say you have 1 parent and 3 children match your condition, it will return 4 documents. 1 parent document and 3 children documents. I guess you probably want to have just 3 documents with some of the parent fields and child fields together.

That is what I want to solve next.

Hope this helps you.

1

This could be the most efficient way to do it, using "inner_hits" for parent/child relationship

Refer:https://github.com/elastic/elasticsearch/pull/8153

Photon
  • 180
  • 2
  • 8
  • Thanks, it's really helpful. Related docs: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-inner-hits.html – songyy May 24 '16 at 06:58
  • Any idea if you could add match filters to both parent and child documents? – Righto Mar 08 '18 at 05:46