ruby-on-railselasticsearchelasticsearch-rails

Yield/add search term to ElasticSearch results


I'm doing a ElasticSearch query with multiple terms constructed dynamically, so it looks like this:

...
must: [
  { terms: { tags_slug: ['term_a', 'term_b'] } },
  ...
]
...

everything works fine, but I'd like to add to each result, the term that it had match with, so, if for instance the result #1 matched term_a, I'd like somehow to be able to get that term from the current result, something like this:

Model.search(...).results[0].matched_term # => 'term_a'
Model.search(...).results[1].matched_term # => 'term_b'

As an example, is there a possibility to do this with Elasticsearch? I could do it with Ruby by mapping the results, but maybe there's another way to do it.


Solution

  • Under the current constellation, no. But since the terms query is effectively a bunch of bool-shoulds we can take advantage of named queries like so:

    {
      "query": {
        "bool": {
          "should": [
            {
              "term": {
                "tags_slug": {
                  "_name": "term_a",
                  "value": "term_a"
                }
              }
            },
            {
              "term": {
                "tags_slug": {
                  "_name": "term_b",
                  "value": "term_b"
                }
              }
            }
          ]
        }
      }
    }
    

    yielding

    [
      {
        "_index":"tags",
        "_type":"_doc",
        "_id":"s0tOBHUBeQiv5rwb5JPA",
        "_score":0.6931472,
        "_source":{
          "tags_slug":"term_a"
        },
        "matched_queries":[        <---
          "term_a"
        ]
      },
      {
        "_index":"tags",
        "_type":"_doc",
        "_id":"tEtPBHUBeQiv5rwbAZPt",
        "_score":0.6931472,
        "_source":{
          "tags_slug":"term_b"
        },
        "matched_queries":[       <---
          "term_b"
        ]
      }
    ]