【问题标题】:Elastic search results are not as expected弹性搜索结果不如预期
【发布时间】:2020-09-16 19:12:10
【问题描述】:

我有一个使用以下配置的自定义分析器索引的字段

 "COMPNAYNAME" : {
          "type" : "text",
          "analyzer" : "textAnalyzer"
        }

 "textAnalyzer" : {
              "filter" : [
                "lowercase"
              ],
              "char_filter" : [ ],
              "type" : "custom",
              "tokenizer" : "ngram_tokenizer"
            }

 "tokenizer" : {
            "ngram_tokenizer" : {
              "type" : "ngram",
              "min_gram" : "2",
              "max_gram" : "3"
            }
          }

当我在搜索文本“ikea”时,我得到了以下结果

查询:

GET company_info_test_1/_search
{
  "query": {
    "match": {
      "COMPNAYNAME": {"query": "ikea"}
    }
  }
}

放纵是结果,

1.mikea
2.likeable
3.maaikeart
4.likeables
5.ikea b.v.  <------
6.likeachef
7.ikea breda <------
8.bernikeart
9.ikea duiven
10.mikea media

我预计完全匹配的结果应该比其他结果得到更多的提升。 如果我必须以精确匹配和泡沫进行搜索,您能否帮助我建立索引的最佳方式。

提前致谢。

【问题讨论】:

  • 在搜索时也使用 ngram 标记器不是一个好主意。通常的做法是在索引时启动 ngrams(生成前缀、中缀、后缀标记),然后在搜索时使用 standard 分析器......否则你也会失去精度和匹配许多不相关的文件。您已经可以通过将"search_analyzer": "standard" 添加到您的字段映射来改进您所拥有的。
  • @MoulaliShaik 你有机会看我的回答吗,期待得到你的反馈????
  • 是的,你是对的。但就我而言,我也必须进行模糊处理。我尝试了以下查询,它帮助我提高了我的结果。 ` "query": {"bool": { "should": [ { "span_first": { "match": { "span_term": { "HANDELSNM": "ikea" } }, "end": 3 } }, {“匹配”:{“HANDELSNM”:{“查询”:“宜家”}}}]}}`

标签: elasticsearch


【解决方案1】:

您可以将ngram tokenizer"search_analyzer": "standard" 一起使用,请参阅此以了解有关search_analyzer 的更多信息

正如@EvaldasBuinauskas 所指出的,如果您希望仅从开头而不是从中间生成令牌,您也可以在此处使用edge_ngram tokenizer

添加一个包含索引数据、映射、搜索查询和结果的工作示例

索引数据:

{ "title": "ikea b.v."}
{ "title" : "mikea" }
{ "title" : "maaikeart"}

索引映射

{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_analyzer": {
                    "tokenizer": "my_tokenizer"
                }
            },
            "tokenizer": {
                "my_tokenizer": {
                    "type": "ngram",
                    "min_gram": 2,
                    "max_gram": 10,
                    "token_chars": [
                        "letter",
                        "digit"
                    ]
                }
            }
        },
        "max_ngram_diff": 50
    },
    "mappings": {
        "properties": {
            "title": {
                "type": "text",
                "analyzer": "my_analyzer",
                "search_analyzer": "standard"
            }
        }
    }
}

搜索查询:

{
    "query": {
        "match" : {
            "title" : "ikea"
        }
    }
}

搜索结果:

"hits": [
            {
                "_index": "normal",
                "_type": "_doc",
                "_id": "4",
                "_score": 0.1499838,    <-- note this
                "_source": {
                    "title": "ikea b.v."
                }
            },
            {
                "_index": "normal",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.13562363,    <-- note this
                "_source": {
                    "title": "mikea"
                }
            },
            {
                "_index": "normal",
                "_type": "_doc",
                "_id": "3",
                "_score": 0.083597526,
                "_source": {
                    "title": "maaikeart"
                }
            }
        ]

【讨论】:

  • 我还建议使用edge_ngram 而不是ngram。这不会从单词中间产生标记。
  • @EvaldasBuinauskas 是的,如果 OP 只想从头开始生成令牌,我们也可以在这里使用 edge_ngrams。感谢您指出这一点:)
  • @EvaldasBuinauskas 如果您喜欢这个答案,请不要忘记也给这个赞投票?
猜你喜欢
  • 2021-07-12
  • 2016-08-05
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-02-10
相关资源
最近更新 更多