FindingTheOne
FindingTheOne

Reputation: 189

Search across _all field in Elastic and return results with highlighting

I am using Elastic 5.4 and wanted to query across index containing documents of multiple types.(type a and type b). Below are example documents in the index:

Documents:

{
  "_index": "test",
  "_type": "a",
  "_id": "1",
  "_source": {
    "id": "1",
    "name": "john-usa-soccer",
    "class": "5",
    "lastseen": "2017-07-05",
    "a_atts": {
      "lastname": "tover",
      "hobby": "soccer",
      "country": "usa"
    }
  }
}

 {
  "_index": "test",
  "_type": "b",
  "_id": "2",
  "_source": {
    "id": "2",
    "name": "john-usa",
    "class": "5",
    "lastseen": "2017-07-05",
    "b_atts": {
      "lastname": "kaml",
      "hobby": "baseball",
      "country": "usa"
    }
  }
}

Mapping:

{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_ngram_analyzer": {
          "tokenizer": "my_ngram_tokenizer"
        }
      },
      "tokenizer": {
        "my_ngram_tokenizer": {
          "type": "ngram",
          "min_gram": "3",
          "max_gram": "3",
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    }
  },
  "mappings": {
    "a": {
      "dynamic_templates": [
        {
          "strings": {
            "match": "*",
            "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "analyzer": "my_ngram_analyzer",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                },
                "suggest": {
                  "type": "completion",
                  "analyzer": "simple"
                },
                "analyzer1": {
                  "type": "text",
                  "analyzer": "simple"
                },
                "analyzer2": {
                  "type": "text",
                  "analyzer": "standard"
                }
              }
            }
          }
        }
      ]
    },
    "b": {
      "dynamic_templates": [
        {
          "strings": {
            "match": "*",
            "match_mapping_type": "string",
            "mapping": {
              "type": "text",
              "analyzer": "my_ngram_analyzer",
              "fields": {
                "keyword": {
                  "type": "keyword",
                  "ignore_above": 256
                },
                "suggest": {
                  "type": "completion",
                  "analyzer": "simple"
                },
                "analyzer1": {
                  "type": "text",
                  "analyzer": "simple"
                },
                "analyzer2": {
                  "type": "text",
                  "analyzer": "standard"
                }
              }
            }
          }
        }
      ]
    }
  }
}

My query is to search all documents which contain 'john' across any of the fields in any type and highlight the fields where the match was found. This query is constructed as per Elastic documentation. My Schema mappings has ngram_analyzer configured as analyzer instead of default analyzer for all fields of type string in the schema.

Query: http://localhost:9200/student/_search

{
  "query": {
    "bool": {
      "should": [
        { "match": { "_all": "john"} }
      ]
    }
  },
  "highlight": {
    "fields": {
      "name": { 
        "require_field_match": false
      },
      "a_atts.lastname":{
        "require_field_match": false
      },
      "a_atts.hobby":{
        "require_field_match": false
      },
      "a_atts.country":{
        "require_field_match": false
      }
    }
  }
}

Response:

{
  "took": 79,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.17669111,
    "hits": [
      {
        "_index": "student",
        "_type": "a",
        "_id": "AV1WjBeYEZrDBYsdGMtY",
        "_score": 0.17669111,
        "_source": {
          "name": "john-usa-soccer",
          "class": "5",
          "lastseen": "2017-07-05",
          "a_atts": {
            "lastname": "tover",
            "hobby": "soccer",
            "country": "usa"
          }
        }
      },
      {
        "_index": "student",
        "_type": "b",
        "_id": "AV1WjHFxEZrDBYsdGMtZ",
        "_score": 0.17669111,
        "_source": {
          "name": "john-usa",
          "class": "5",
          "lastseen": "2017-07-05",
          "b_atts": {
            "lastname": "kaml",
            "hobby": "baseball",
            "country": "usa"
          }
        }
      }
    ]
  }
}

However, executing the above query against an index, returns documents matched with their _source content but not highlight field. It is missing the following:

    "highlight": {
      "name": [
        "<em>john</em>-usa-soccer"
      ]
    }

How can I return highlight in the results?

Upvotes: 0

Views: 1279

Answers (1)

FindingTheOne
FindingTheOne

Reputation: 189

I got highlighter to work by following the answer provided in this link.

"highlight": {
    "fields": {
      "*": {}
    },
    "require_field_match": false
 }

Upvotes: 2

Related Questions