【问题标题】:How to match parts of a word in elasticsearch?如何在elasticsearch中匹配单词的一部分?
【发布时间】:2016-03-01 17:20:19
【问题描述】:

如何将单词的部分内容与父单词匹配?例如:我需要将“eese”或“heese”与“cheese”一词匹配。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    实现此目的的最佳方法是使用一个edgeNGram token filter 和两个reverse token filters。因此,首先您需要在索引设置中定义一个名为 reverse_analyzer 的自定义分析器,如下所示。然后你可以看到我已经声明了一个名为 your_field 的字符串字段和一个名为 suffix 的子字段,其中定义了我们的自定义分析器。

    PUT your_index
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "reverse_analyzer": {
              "tokenizer": "keyword",
              "filter" : ["lowercase", "reverse", "substring", "reverse"]
            }
          },
          "filter": {
            "substring": {
              "type": "edgeNGram",
              "min_gram": 1,
              "max_gram": 10
            }
          }
        }
      },
      "mappings": {
        "your_type": {
          "properties": {
            "your_field": {
              "type": "string",
              "fields": {
                "suffix": {
                  "type": "string",
                  "analyzer": "reverse_analyzer"
                }
              }
            }
          }
        }
      }
    }
    

    然后你可以索引一个里面有“cheese”的测试文档,像这样:

    PUT your_index/your_type/1
    {"your_field": "cheese"}
    

    当此文档被索引时,your_field.suffix 字段将包含以下标记:

    • e
    • se
    • ese
    • eese
    • heese
    • cheese

    在索引cheese 时发生的情况如下:

    1. keyword 标记器将标记单个标记,=> cheese
    2. lowercase 标记过滤器会将标记放入小写 => cheese
    3. reverse 令牌过滤器将反转令牌 => eseehc
    4. substring 标记过滤器将生成长度为 1 到 10 的不同标记 => e、es、ese、esee、eseeh、eseehc
    5. 最后,第二个 reverse 令牌过滤器将再次反转所有令牌 => e,se,ese,eese,heese,cheese
    6. 这些都是将被索引的标记

    所以我们最终可以在该子字段中搜索eese(或cheese 的任何后缀)并找到我们的匹配项

    POST your_index/_search
    {
       "query": {
          "match": {
             "your_field.suffix": "eese"
          }
       }
    }
    

    => 生成我们刚刚在上面索引的文档。

    【讨论】:

    • 嗨,有没有办法让它同时适用于后缀和前缀。即)索引词“Cheese”,我想用“2chee”或“Cheese2”搜索它
    • @The6thSense 是的,请参阅我的 other question 并查找如何解决 substringof 问题
    【解决方案2】:

    您可以通过两种方式做到这一点:

    1. 如果你只需要它发生在一些搜索然后搜索框只有你可以通过

      *eese* 或 *heese*

    只需在搜索词的开头和结尾输入 *。如果您每次搜索都需要它

     string "*#{params[:query]}*"
    

    这将与您的父单词匹配并给出结果

    【讨论】:

      【解决方案3】:

      有多种方法可以做到这一点

      1. 分析器方法 - 在这里你 Ngram tokenizer 打破所有单词的子标记。因此,对于单词 "cheese" -> [ "chee" , "hees" , "eese" , "cheese" ] 和所有子字符串的 ind 都会生成。有了这个索引大小会变高,但搜索速度会得到优化

      2. wildcard query 方法 - 在这种方法中,对反向索引进行扫描。这不会占用额外的索引大小,但会花费更多时间进行搜索。

      【讨论】:

        猜你喜欢
        • 2018-11-01
        • 2016-10-10
        • 2013-08-08
        • 2020-02-02
        • 1970-01-01
        • 1970-01-01
        • 2016-05-15
        • 2018-10-19
        • 2013-10-28
        相关资源
        最近更新 更多