Aggregating child highlights into parent's score and result

I am trying to implement Elasticsearch for a forum (among other things), where we have Forum, Topics and Replies, each being a child of the previous. We can ignore Forum for now and just focus on the Topics and Replies as a simple parent-child Join.

I only want Topics to be returned as search results, however I want the Topic's score to reflect any search term matches in its child Replies.

Moreover (and where things probably get most complicated), I'd like to return all of the highlighted fragments from the child Replies with the Topic (which I can then manipulate in my application code before displaying it).

It seems like I need to do some sort of child aggregation with inner_hits, but I really don't know how to implement it.

Can someone please point me in the right direction?

Thanks!

I figured this out - it was not hard at all thanks to how fantastic ES is!

If I map an index as follows

PUT forums
{
  "mappings": {
    "properties": {
      "id": {
        "type": "short"
      },
      "title": {
        "type": "text"
      },
      "content": {
        "type": "text"
      },
      "forum_relation": { 
        "type": "join",
        "relations": {
          "topic": "reply" 
        }
      }
    }
  }
}

A query with the following basic structure seems to do what I need it to, namely return the Topics based on the content of its child Replies, and return the matched highlights/fragments from each of those "inner_hits" Replies.

GET /forums/_search
{
  "query": {
    "has_child": {
      "type": "reply",
      "query": {
        "match": {
          "content": "asdf"
        }
      },
      "score_mode": "avg",
      "inner_hits": {
        "_source": {
          "includes": [
            "id",
            "forum_relation.name"
          ]
        },
        "highlight": {
          "fields": {
            "content": {}
          },
          "fragment_size": 100,
          "number_of_fragments": 2
        }
      }
    }
  }
}

Here is an excerpt of the result

"hits" : [      
  {
    "_index" : "forums",
    "_type" : "_doc",
    "_id" : "8",
    "_score" : 0.30370584,
    "_routing" : "1",
    "_source" : {
      "id" : "8",
      "title" : "TOPIC 3",
      "content" : "CONTENT 3",
      "forum_relation" : {
        "name" : "topic"
      }
    },
    "inner_hits" : {
      "reply" : {
        "hits" : {
          "total" : {
            "value" : 7,
            "relation" : "eq"
          },
          "max_score" : 0.5179415,
          "hits" : [
            {
              "_index" : "forums",
              "_type" : "_doc",
              "_id" : "15",
              "_score" : 0.5179415,
              "_routing" : "1",
              "_source" : {
                "forum_relation" : {
                  "name" : "reply"
                },
                "id" : "15"
              },
              "highlight" : {
                "content" : [
                  "convallis felis, ullamcorper orci rhoncus maecenas erat cursus blandit, ridiculus porttitor aenean null <em>asdf</em>",
                  "Ut sapien commodo porttitor <em>asdf</em> accumsan per sollicitudin odio ultricies maecenas orci, arcu semper"
                ]
              }
            },
            {
              "_index" : "forums",
              "_type" : "_doc",
              "_id" : "9",
              "_score" : 0.2679999,
              "_routing" : "1",
              "_source" : {
                "forum_relation" : {
                  "name" : "reply"
                },
                "id" : "9"
              },
              "highlight" : {
                "content" : [
                  "montes ridiculus rutrum fames risus, donec nostra tincidunt ultricies platea elementum cursus erat. <em>asdf</em>"
                ]
              }
            },
            {
              "_index" : "forums",
              "_type" : "_doc",
              "_id" : "10",
              "_score" : 0.2679999,
              "_routing" : "1",
              "_source" : {
                "forum_relation" : {
                  "name" : "reply"
                },
                "id" : "10"
              },
              "highlight" : {
                "content" : [
                  "montes ridiculus rutrum fames risus, donec nostra tincidunt ultricies platea elementum cursus erat. <em>asdf</em>"
                ]
              }
            }
          ]
        }
      }
    }
  }
]

I can then easily extract and manipulate the highlight arrays as-needed on the application side, PHP in this case.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.