我正在尝试使用elasticsearch使用ngrams进行名称搜索匹配,
我试图实现的技术如下:
input:需要与db匹配的名称
输出:从我的名字db中匹配的所有潜在名称。
我尝试这样做的方式如下,我将名称拆分为长度为3-5的ngrams 然后我从db收集所有与那些ngram相匹配的名称 然后我查看ngrams并按反向频率对它们进行排序 意思是普通的ngrams得分最低 例如,如果我在公司名称上使用它,例如“我公司公司”,我会给“inc”ngram一个最低分,因为inc出现在很多公司名称中。
我计算分数的方法是:1 /(计算我所有数据库中ngram的出现次数),这样我就会得到“最强”的ngrams作为那些看起来最少的ngram。
我在python脚本中实现了这个,但我想使用弹性的力量为我做同样的事情,
我知道ngram标记器,但有没有办法告诉他做我的分数?
据我所知,当我现在进行匹配时,它会根据查询中有多少ngram与数据库中的ngrams匹配得分结果
这是我使用的映射:
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 5,
"token_chars": ["letter", "digit"]
}
}
}
},
"mappings": {
"names": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256,
}
},
"analyzer": "my_analyzer"
},
"id": {
"type": "long"
}
}
}
}
}
这是我的查询:
GET /names/_search
{
"query": {
"match" : { "name" : "my company inc"}
}
}
答案 0 :(得分:1)
您要使用的查询是:
{
"query": {
"common": {
"name": {
"query": "my company inc",
"cutoff_frequency": 0.001
}
}
}
}
常用术语查询仅基于重要术语(重要的nGrams)返回相关性分数,即频率较低的术语。在这里,文档频率大于0.1%的单词将被视为常用单词,不会影响相关性分数。
或者,如果您已经有预定义的停用词列表(inc,pvt,ltd),那么您始终可以在分析器中使用自定义停用词过滤器来过滤它们以生成命中。
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer",
"filter": [
"custom_stop_token_filter"
]
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 5,
"token_chars": ["letter", "digit"]
}
},
"filter": {
"custom_stop_token_filter": {
"type": "stop",
"stopwords": [
"inc",
"pvt",
"ltd"
]
}
}
}
}
}
欲了解更多信息: