如何匹配elasticsearch中的单词部分?

时间:2015-11-27 13:30:35

标签: elasticsearch

如何将单词的某些部分与父单词匹配?例如:我需要匹配" eese"或者" heese" to the#34; cheese"。

3 个答案:

答案 0 :(得分:4)

实现此目标的最佳方法是使用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 =>的不同令牌。 eeseseeseeeseeheseehc
  5. 最后,第二个reverse令牌过滤器将再次反转所有令牌=> eseeseeeseheesecheese
  6. 这些都是将被编入索引的令牌
  7. 因此,我们最终可以在该子字段中搜索eese(或cheese的任何后缀)并找到我们的匹配

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

    =>产生我们刚刚索引的文档。

答案 1 :(得分:0)

你可以用两种方式做到:

  1. 如果您只需要搜索某些搜索框,那么只有搜索框可以传递

    * eese *或* heese *

  2. 在搜索词的开头和结尾添加*。如果每次搜索都需要它

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

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

答案 2 :(得分:0)

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

  1. 分析器方法 - 在这里Ngram tokenizer打破所有单词的子标记。因此,对于“奶酪”这个词 - >将产生[“chee”,“hees”,“eese”,“cheese”]和所有子串。使用此索引大小会很高,但搜索速度会得到优化

  2. wildcard query方法 - 在此方法中,扫描发生在反向索引上。这不占用额外的索引大小,但搜索需要更多时间。