名称的弹性匹配查询
Elastic matchQuery for name
我有一个包含用户名的弹性字段,例如。我的名字会包含 vojtech knyttl
.
我正在尝试创建一个匹配查询,以便能够通过以下短语找到我的名字:
vojtech k
vojtech kny
knyttl
我的查询:
{
"bool" : {
"should" : [
{
"match" : {
"keywords" : {
"query" : "vojtech kn",
"operator" : "AND",
"prefix_length" : 0,
"max_expansions" : 50,
"minimum_should_match" : "50%",
}
}
}
]
}
}
问题是 vojtech
和 vojtech kn
由于 AND
运算符而找不到任何东西。如果我切换到 OR
,搜索 vojtech knyttl
实际上会 select 数据库中的每个 vojtech
而我的姓氏甚至不会出现在最前面的结果中。
对于这样的搜索应该如何形成查询?
您应该使用 match phrase prefix query,在下面的示例中对其进行了测试,根据您的 use-case,它似乎工作正常。
示例文档
{
"name" : "vojtech knyttl"
}
{
"name" : "vojtech"
}
{
"name" : "vojtech kn"
}
使用匹配词组前缀的搜索查询
{
"query": {
"match_phrase_prefix": {
"name": {
"query": "vojtech k"
}
}
}
}
我认为 edge_ngrams 应该适用于这种情况。
请尝试以下操作:
设置索引以使用 edge_ngrams 作为索引分析器。
PUT test
{
"mappings": {
"properties": {
"name":{
"type": "text",
"analyzer": "custom_analyzer",
"search_analyzer": "standard"
}
}
},
"settings": {
"analysis": {
"filter": {
"custom_edge_ngram":
{
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 10
}
},
"analyzer": {
"custom_analyzer":{
"tokenizer":"standard",
"filter":[
"lowercase",
"custom_edge_ngram"]
}
}
}
}
}
然后使用以下查询查询索引:
GET test/_search
{
"query": {
"match": {
"name":
{
"query":"vojtech k",
"operator": "and"
}
}
}
}
解释:
边缘 ngram 索引分析器将为索引中的名称字段生成最小长度为 1 且最大长度为 10 的 ngram
您可以使用此检查令牌:
GET test/_analyze
{
"analyzer": "custom_analyzer",
"text": ["vojtech knyttl"]
}
当您使用匹配查询进行搜索时,它会在您的文档中找到 vojtech 和 k 作为 ngram。
我的测试用例
vojtech 亚当斯, vojtech knyttl, vojtech, 乔·克尼特
如果我搜索 vojtech knyttl it returns 1 个结果。
如果我搜索 vojtech,我会得到 vojtech adams、vojtech knyttl、vojtech
如果我搜索 vojteck k 我会得到 vojtech knyttl
如果我搜索 knyttl,我会得到 vojtech knyttl,joe knyttl
我有一个包含用户名的弹性字段,例如。我的名字会包含 vojtech knyttl
.
我正在尝试创建一个匹配查询,以便能够通过以下短语找到我的名字:
vojtech k
vojtech kny
knyttl
我的查询:
{
"bool" : {
"should" : [
{
"match" : {
"keywords" : {
"query" : "vojtech kn",
"operator" : "AND",
"prefix_length" : 0,
"max_expansions" : 50,
"minimum_should_match" : "50%",
}
}
}
]
}
}
问题是 vojtech
和 vojtech kn
由于 AND
运算符而找不到任何东西。如果我切换到 OR
,搜索 vojtech knyttl
实际上会 select 数据库中的每个 vojtech
而我的姓氏甚至不会出现在最前面的结果中。
对于这样的搜索应该如何形成查询?
您应该使用 match phrase prefix query,在下面的示例中对其进行了测试,根据您的 use-case,它似乎工作正常。
示例文档
{
"name" : "vojtech knyttl"
}
{
"name" : "vojtech"
}
{
"name" : "vojtech kn"
}
使用匹配词组前缀的搜索查询
{
"query": {
"match_phrase_prefix": {
"name": {
"query": "vojtech k"
}
}
}
}
我认为 edge_ngrams 应该适用于这种情况。 请尝试以下操作:
设置索引以使用 edge_ngrams 作为索引分析器。
PUT test
{
"mappings": {
"properties": {
"name":{
"type": "text",
"analyzer": "custom_analyzer",
"search_analyzer": "standard"
}
}
},
"settings": {
"analysis": {
"filter": {
"custom_edge_ngram":
{
"type": "edge_ngram",
"min_gram": 1,
"max_gram": 10
}
},
"analyzer": {
"custom_analyzer":{
"tokenizer":"standard",
"filter":[
"lowercase",
"custom_edge_ngram"]
}
}
}
}
}
然后使用以下查询查询索引:
GET test/_search
{
"query": {
"match": {
"name":
{
"query":"vojtech k",
"operator": "and"
}
}
}
}
解释:
边缘 ngram 索引分析器将为索引中的名称字段生成最小长度为 1 且最大长度为 10 的 ngram
您可以使用此检查令牌:
GET test/_analyze
{
"analyzer": "custom_analyzer",
"text": ["vojtech knyttl"]
}
当您使用匹配查询进行搜索时,它会在您的文档中找到 vojtech 和 k 作为 ngram。
我的测试用例 vojtech 亚当斯, vojtech knyttl, vojtech, 乔·克尼特
如果我搜索 vojtech knyttl it returns 1 个结果。
如果我搜索 vojtech,我会得到 vojtech adams、vojtech knyttl、vojtech
如果我搜索 vojteck k 我会得到 vojtech knyttl
如果我搜索 knyttl,我会得到 vojtech knyttl,joe knyttl