【发布时间】:2016-03-01 17:20:19
【问题描述】:
如何将单词的部分内容与父单词匹配?例如:我需要将“eese”或“heese”与“cheese”一词匹配。
【问题讨论】:
标签: elasticsearch
如何将单词的部分内容与父单词匹配?例如:我需要将“eese”或“heese”与“cheese”一词匹配。
【问题讨论】:
标签: elasticsearch
实现此目的的最佳方法是使用一个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 字段将包含以下标记:
eseeseeeseheesecheese在索引cheese 时发生的情况如下:
keyword 标记器将标记单个标记,=> cheese
lowercase 标记过滤器会将标记放入小写 => cheese
reverse 令牌过滤器将反转令牌 => eseehc
substring 标记过滤器将生成长度为 1 到 10 的不同标记 => e、es、ese、esee、eseeh、eseehc reverse 令牌过滤器将再次反转所有令牌 => e,se,ese,eese,heese,cheese
所以我们最终可以在该子字段中搜索eese(或cheese 的任何后缀)并找到我们的匹配项
POST your_index/_search
{
"query": {
"match": {
"your_field.suffix": "eese"
}
}
}
=> 生成我们刚刚在上面索引的文档。
【讨论】:
substringof 问题
您可以通过两种方式做到这一点:
如果你只需要它发生在一些搜索然后搜索框只有你可以通过
*eese* 或 *heese*
只需在搜索词的开头和结尾输入 *。如果您每次搜索都需要它
string "*#{params[:query]}*"
这将与您的父单词匹配并给出结果
【讨论】:
有多种方法可以做到这一点
分析器方法 - 在这里你 Ngram tokenizer 打破所有单词的子标记。因此,对于单词 "cheese" -> [ "chee" , "hees" , "eese" , "cheese" ] 和所有子字符串的 ind 都会生成。有了这个索引大小会变高,但搜索速度会得到优化
wildcard query 方法 - 在这种方法中,对反向索引进行扫描。这不会占用额外的索引大小,但会花费更多时间进行搜索。
【讨论】: