【问题标题】:How to highlight characters within words using elasticsearch如何使用弹性搜索突出显示单词中的字符
【发布时间】:2020-01-14 16:44:23
【问题描述】:

我已经使用弹性搜索实现了自动建议,我根据键入的值'where' 向用户提供建议。
如果我输入完整的单词或单词的几个起始字符,大部分部分都可以正常工作。
我想突出显示用户输入的特定字符,例如用户输入 'ca' 然后建议应仅突出显示“California”而不是整个单词“California” >'
突出显示标记应显示类似<b>Ca</b>lifornia 而不是<b>California</b> 的结果。

这是我的索引设置

 {
      "settings": {
        "index": {
          "analysis": {
            "filter": {
              "edge_filter": {
                "type": "edge_ngram",
                "min_gram": 1,
                "max_gram": 50
              },
              "lowercase_filter":{
                "type":"lowercase",
                "language": "greek"
              },
              "metro_synonym": {
                "type": "synonym",
                "synonyms_path": "metro_synonyms.txt"
              },
              "profession_specialty_synonym": {
                "type": "synonym",
                "synonyms_path": "profession_specialty_synonyms.txt"
              }
            },
            "analyzer": {
              "auto_suggest_analyzer": {
                "filter": [
                  "lowercase",
                  "edge_filter"
                ],
                "type": "custom",
                "tokenizer": "whitespace"
              },
              "auto_suggest_search_analyzer": {
                "filter": [
                  "lowercase"
                ],
                "type": "custom",
                "tokenizer": "whitespace"
              },
              "lowercase": {
                "filter": [
                  "trim",
                  "lowercase"
                ],
                "type": "custom",
                "tokenizer": "keyword"
              }
            }
          }
        }
      },
      "mappings": {
        "properties": {
          "what_auto_suggest": {
            "type": "text",
            "analyzer": "auto_suggest_analyzer",
            "search_analyzer": "auto_suggest_search_analyzer",
            "fields": {
              "raw":{
                "type":"keyword"
              }
            }
          },
          "company": {
            "type": "text",
            "analyzer": "lowercase"
          },
          "where_auto_suggest": {
            "type": "text",
            "analyzer": "auto_suggest_analyzer",
            "search_analyzer": "auto_suggest_search_analyzer",
            "fields": {
              "raw":{
                "type":"keyword"
              }
            }
          },
          "tags_auto_suggest": {
            "type": "text",
            "analyzer": "auto_suggest_analyzer",
            "search_analyzer": "auto_suggest_search_analyzer",
            "fields": {
              "raw":{
                "type":"keyword"
              }
            }
          }
        }
      }
    }


我用来提取建议的查询 -

GET /autosuggest_index_test/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "where_auto_suggest": {
              "query": "ca",
              "operator": "and"
            }
          }
        }
      ]
    }
  },
  "aggs": {
    "NAME": {
      "terms": {
        "field": "where_auto_suggest.raw",
        "size": 10
      }
    }
  },
  "highlight": {
    "pre_tags": [
      "<b>"
    ],
    "post_tags": [
      "</b>"
    ],
    "fields": {
      "where_auto_suggest": {
      }
    }
  }
}


我得到的 json 结果之一 -

  {
    "_index" : "autosuggest_index_test",
    "_type" : "_doc",
    "_id" : "Calabasas CA",
    "_score" : 5.755663,
    "_source" : {
      "where_auto_suggest" : "Calabasas CA"
    },
    "highlight" : {
      "where_auto_suggest" : [
        "<b>Calabasas</b> <b>CA</b>"
      ]
    }
  }

有人可以建议,如何在此处(在 where_auto_suggest 中)获得输出,例如 - "&lt;b&gt;Ca&lt;/b&gt;labasas &lt;b&gt;CA&lt;/b&gt;"

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    我真的不知道为什么,但是如果您使用 edge_ngram tokenizer 而不是 edge_ngram 过滤器,您将突出显示字符而不是突出显示的单词。

    所以在你的设置中,你可以声明这样一个分词器:

    "settings": {
        "index": {
            "analysis": {
                "tokenizer": {
                    "edge_tokenizer": {
                        "type": "edge_ngram",
                        "min_gram": 1,
                        "max_gram": 50,
                        "token_chars": [
                            "letter",
                            "digit",
                            "punctuation",
                            "symbol"
                        ]
                    }
                },
                ...
            }
        }
    }
    

    并将您的分析仪更改为:

    "analyzer": {
        "auto_suggest_analyzer": {
            "filter": [
                "lowercase"
            ],
            "type": "custom",
            "tokenizer": "edge_tokenizer"
        }
        ...
    }
    

    因此您的示例请求将返回

    {
        ...
        "hits": {
            "total": {
                "value": 1,
                "relation": "eq"
            },
            "max_score": 0.2876821,
            "hits": [
                {
                    "_index": "autosuggest_index_test",
                    "_type": "_doc",
                    "_id": "grIzo28BY9R4-IxJhcFv",
                    "_score": 0.2876821,
                    "_source": {
                        "where_auto_suggest": "california"
                    },
                    "highlight": {
                        "where_auto_suggest": [
                            "<b>ca</b>lifornia"
                        ]
                    }
                }
            ]
        }
        ...
    }
    

    【讨论】:

    • 感谢@Pierre 提供的时间和解决方案。 Edge N-Grams 分词器对于搜索即键入查询很有用。我认为生成的术语不符合我的要求,并且认为这是我使用标记器空白时的问题。
    猜你喜欢
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 1970-01-01
    • 2012-05-21
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多