【问题标题】:Elasticsearch index and search time analyzer for field mapping doesn't work用于字段映射的 Elasticsearch 索引和搜索时间分析器不起作用
【发布时间】:2020-06-08 19:00:11
【问题描述】:

我是 elasticsearch 新手,我想提供“键入时搜索”功能。要搜索的文本每个字段不超过 50 个字符。搜索应该找到包含搜索文本的所有文档。类似于“通配符术语”à la '*query*'。但这是非常耗费成本的。

这就是为什么我尝试按照这篇文章https://www.elastic.co/guide/en/elasticsearch/reference/current/search-analyzer.html的描述来做。就我而言,唯一的区别是我想使用“n-gram”分析器而不是“edge n-gram”分析器。

我创建了以下自定义分析器:

     "settings": {
         "index": {
             "max_ngram_diff": "50",
             [...]
             "analysis": {
                 "filter": {
                     "3-50-grams-filter": {
                     "type": "ngram",
                     "min_gram": "3",
                     "max_gram": "50"
                  }
             },
             "analyzer": {
                 "index-3-50-grams-analyzer": {
                     "filter": [
                         "lowercase",
                         "3-50-grams-filter"
                     ],
                     "type": "custom",
                     "tokenizer": "keyword"
                 },
                 "search-3-50-grams-analyzer": {
                     "filter": [
                         "lowercase"
                     ],
                     "type": "custom",
                     "tokenizer": "keyword"
              }

我创建了以下映射:

"mappings": {
    dynamic": "strict",
    properties": {
        "my-field": {
                "type": "text",
                "fields": {
                    "my-field": {
                        "type": "text",
                        "analyzer": "index-3-50-grams-analyzer",
                        "search_analyzer": "search-3-50-grams-analyzer"
                    },
                    "keyword": {
                        "type": "keyword",
                        "ignore_above": 256
                    }
                }
            },

发布以下数据:

{
    "my-field": "1107811#1OMAH0RN03D2"
}

将以下内容发送到分析 API:

{
    "text" : "1107811#1OMAH0RN03D2",
    "field" : "my-field"
}

得到以下结果:

{
    "tokens": [
        {
            "token": "1107811",
            "start_offset": 0,
            "end_offset": 7,
            "type": "<NUM>",
            "position": 0
        },
        {
            "token": "1omah0rn03d2",
            "start_offset": 8,
            "end_offset": 20,
            "type": "<ALPHANUM>",
            "position": 1
        }
    ]
}
  1. 似乎 search_analyzer(虽然在字段映射中定义)无法自动工作
  2. 即使我在查询中指定了 search_analyzer,我也没有得到预期的结果。

这样的查询会找到文档:

"query": {
    "match": {
        "my-field": {
            "query": "1OMAH0RN03D2"
        }
    }
}

...但是这样的查询不会(只是删除了第一个字符):

"query": {
    "match": {
        "my-field": {
            "query": "OMAH0RN03D2"
        }
    }
}

...并且带有显式 search_analyzer 的查询也不会(如果我再删除一个字符):

"query": {
    "match": {
        "my-field": {
            "query": "MAH0RN03D2",
            "analyzer": "search-3-50-grams-analyzer"
        }
    }
}

有谁知道可能导致这种行为的原因是什么?

【问题讨论】:

  • 它为我工作,看起来你错过了什么,请参考我的回答,如果你有其他问题,请告诉我
  • @OpsterElasticsearchNinja :谢谢你的例子。所以我有可能将它与我的配置/映射进行比较,这样我实际上可以找到错误。在我的映射中,该字段被定义为“多字段”,并且分析器定义被分配了更深的级别。这意味着我必须通过以下方式调整我的搜索以使其正常工作:{ "query": { "match": { "my-field.my-field": { query": "1#1OMAH0RN"} } } }

标签: elasticsearch wildcard n-gram analyzer


【解决方案1】:

不确定,但我尝试使用您的示例文档和索引设置进行此操作,对我来说效果很好,下面是我做的一步一步的事情。

索引映射和设置

{
    "settings": {
        "index": {
            "max_ngram_diff": "50",
            "analysis": {
                "filter": {
                    "3-50-grams-filter": {
                        "type": "ngram",
                        "min_gram": "3",
                        "max_gram": "50"
                    }
                },
                "analyzer": {
                    "index-3-50-grams-analyzer": {
                        "filter": [
                            "lowercase",
                            "3-50-grams-filter"
                        ],
                        "type": "custom",
                        "tokenizer": "keyword"
                    },
                    "search-3-50-grams-analyzer": {
                        "filter": [
                            "lowercase"
                        ],
                        "type": "custom",
                        "tokenizer": "standard"
                    }
                }
            }
        }
    },
    "mappings": {
        "properties": {
            "myfield": {
                "type": "text",
                "analyzer": "index-3-50-grams-analyzer",
                "search_analyzer": "search-3-50-grams-analyzer"
            }
        }
    }
}

索引示例文档

{
  "myfield" : "1107811#1OMAH0RN03D2"
}

搜索查询

{
    "query": {
        "match": {
            "myfield": {
                "query": "OMAH0RN03D2"
            }
        }
    }
}

搜索结果

  "hits": [
      {
        "_index": "edgesearch",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.4848835,
        "_source": {
          "myfield": "1107811#1OMAH0RN03D2"
        }
      }
    ]

编辑:根据 cmets,OP 使用的是 multi field,分析器定义被分配了一个更深的级别,这导致了问题,并将此信息包含在查询已解决的问题中。

【讨论】:

    猜你喜欢
    • 2016-10-14
    • 1970-01-01
    • 2018-11-09
    • 2017-05-25
    • 1970-01-01
    • 2014-02-25
    • 1970-01-01
    • 2015-04-20
    • 2023-03-25
    相关资源
    最近更新 更多