Home > OS >  Can't Highlight Dynamic Template Field Value in Elasticsearch
Can't Highlight Dynamic Template Field Value in Elasticsearch

Time:09-22

Follow up to this question.

I have a dynamic template which copies the text of a JSON blob to a single text field, and I'd like to search on that field and highlight matches. Here is my full code for ES 6.5

DELETE /test
PUT /test?include_type_name=true
{
  "settings": {"number_of_shards": 1,"number_of_replicas": 1},
  "mappings": {
    "_doc": {
      "dynamic_templates": [
        {
          "full_name": {
            "match_mapping_type": "string",
            "path_match": "content.*",
            "mapping": {
              "type": "text",
              "copy_to": "content_text"
            }
          }
        }
      ],
      "properties": {
        "content_text": {
          "type": "text"
        },
        "content": {
          "type": "object",
          "enabled": "true"
        }
      }
    }
  }
}

PUT /test/_doc/1?refresh=true
{
  "content": {
    "a": {
      "b": {
        "text": "42"
      }
    }
  }
}

GET /test/_search
{
  "query": {
    "match": {
      "content_text": "42"
    }
  },
  "highlight": {
    "fields": {
      "content_text": {}
    }
  }
}

The response does not show the highlighted content_text

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "content" : {
            "a" : {
              "b" : {
                "text" : "42"
              }
            }
          }
        }
      }
    ]
  }
}

As you can see, the content_text field is not highlight. It's also not in the response at all. How do I get highlights for this field to show up?

CodePudding user response:

This is a tricky one, but will make sense once you read what follows.

As per the official documentation on highlighting, the actual content of a field is required to exist somewhere. So if the field is not stored (i.e. the mapping does not set store to true), the actual _source is loaded and the relevant field is extracted from _source.

In your case, the content_text field doesn't exist in the _source document (i.e. it is just indexed from other text fields present in content.*) and in the mapping, the store parameter is not set to true (it is false by default).

So you simply need to change your mapping to this:

    "content_text": {
      "store": true,
      "type": "text"
    },

And then your query will yield this:

    "highlight" : {
      "content_text" : [
        "<em>42</em>"
      ]
    }
  • Related