【问题标题】:How do I get Elasticsearch to highlight a partial word from a search_as_you_type field?如何让 Elasticsearch 突出显示 search_as_you_type 字段中的部分单词?
【发布时间】:2020-04-27 20:26:18
【问题描述】:

我在设置 search_as_you_type 字段时遇到问题,请按照此处https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-as-you-type.html 的指南突出显示

我将留下一系列命令来重现我所看到的。希望有人可以权衡我所缺少的:)

  1. 创建映射
PUT /test_index
{
  "mappings": {
    "properties": {
      "plain_text": {
        "type": "search_as_you_type",
        "index_options": "offsets",
        "term_vector": "with_positions_offsets"
      }
    }
  }
}
  1. 插入文档
POST /test_index/_doc
{
  "plain_text": "This is some random text"
}
  1. 搜索文档
GET /snippets_test/_search
{
  "query": {
    "multi_match": {
      "query": "rand",
      "type": "bool_prefix",
      "fields": [
        "plain_text",
        "plain_text._2gram",
        "plain_text._3gram",
        "plain_text._index_prefix"
      ]
    }
  },
  "highlight" : {
    "fields" : [
      {
        "plain_text": {
          "number_of_fragments": 1,
          "no_match_size": 100
        } 
      }
    ]
  }
}
  1. 回复
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "rLZkjm8BDC17cLikXRbY",
        "_score" : 1.0,
        "_source" : {
          "plain_text" : "This is some random text"
        },
        "highlight" : {
          "plain_text" : [
            "This is some random text"
          ]
        }
      }
    ]
  }
}

我得到的回复没有我期望的突出显示 理想情况下,亮点是:This is some <em>ran</em>dom text

【问题讨论】:

    标签: elasticsearch elasticsearch-2.0 elasticsearch-7


    【解决方案1】:

    为了实现 n-grams(字符)的突出显示,您需要:

    • 自定义 ngram 标记器。默认情况下,min_grammax_gram 之间的最大差异为 1,因此在我的示例中,突出显示仅适用于长度为 3 或 4 的搜索词。您可以更改此设置并通过为index.max_ngram_diff.
    • 基于自定义分词器的自定义分析器
    • 在映射中添加“plain_text.highlight”字段

    这是配置:

    {
      "settings": {
        "analysis": {
          "analyzer": {
            "partial_words" : {
              "type": "custom",
              "tokenizer": "ngrams",
              "filter": ["lowercase"]
            }
          },
          "tokenizer": {
            "ngrams": {
              "type": "ngram",
              "min_gram": 3,
              "max_gram": 4
            }
          }
        }
      },
      "mappings": {
        "properties": {
          "plain_text": {
            "type": "text",
            "fields": {
              "shingles": { 
                "type": "search_as_you_type"
              },
              "ngrams": {
                "type": "text",
                "analyzer": "partial_words",
                "search_analyzer": "standard",
                "term_vector": "with_positions_offsets"
              }
            }
          }
        }
      }
    }
    

    查询:

    {
      "query": {
        "multi_match": {
          "query": "rand",
          "type": "bool_prefix",
          "fields": [
            "plain_text.shingles",
            "plain_text.shingles._2gram",
            "plain_text.shingles._3gram",
            "plain_text.shingles._index_prefix",
            "plain_text.ngrams"
          ]
        }
      },
      "highlight" : {
        "fields" : [
          {
            "plain_text.ngrams": { } 
          }
        ]
      }
    }
    

    结果:

        "hits": [
            {
                "_index": "test_index",
                "_type": "_doc",
                "_id": "FkHLVHABd_SGa-E-2FKI",
                "_score": 2,
                "_source": {
                    "plain_text": "This is some random text"
                },
                "highlight": {
                    "plain_text.ngrams": [
                        "This is some <em>rand</em>om text"
                    ]
                }
            }
        ]
    

    注意:在某些情况下,此配置可能会占用内存和存储空间。

    【讨论】:

    • 我已经从 'search_as_you_type' 转移到一个 ngram 分析器,但这个答案仍然适用于我!我仍然需要将我的 ngram 从过滤器移动到标记器。谢谢:)
    • 使用查询“ran”,此解决方案会产生突出显示:“This is some random text”最终突出显示“rand”而不是只突出“跑”。
    • @catalin-m 嘿,这里有一个查询。例如:我有一个像“优秀开发人员”这样的查询,并且我有一些索引,比如“开发人员和测试人员”、“不仅是开发人员”、“优秀的开发人员”、“优秀的测试人员”。然后,当我在您键入时使用搜索进行查询时,我将获得包括开发人员在内的所有索引。你知道为什么吗?
    • @James 您能否分享一下您是如何从“search_as_you_type”迁移到 ngram 分析器的?
    • @Vishnu 很高兴看到您的问题,但这里的评论部分并不是最好的地方。如果没有更多信息,我很难重现您的问题。我的建议是让您按照我的方式编写一些内容:映射/索引、文档创建和查询命令。然后,描述你所看到的,以及为什么这不是你期望看到的。基本上,尽量提供尽可能多的信息,以简化 Answer 的工作。
    猜你喜欢
    • 2013-05-22
    • 2013-07-31
    • 2013-06-29
    • 2015-11-06
    • 1970-01-01
    • 2017-05-24
    • 2015-05-23
    • 2020-08-15
    • 2014-10-23
    相关资源
    最近更新 更多