elasticsearch 同义词分析器给出 0 个结果
elasticsearch synonyms analyzer gives 0 results
我正在使用 elasticsearch 7.0.0
。
我在创建 index
时尝试使用此配置处理 synonyms
。
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "whitespace",
"filter": [
"synonym"
]
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
}
}
}
},
"mappings": {
"properties": {
"address.state": {
"type": "text",
"analyzer": "synonym"
},
"location": {
"type": "geo_point"
}
}
}
}
这是插入索引的文档:
{
"name": "Berry's Burritos",
"description": "Best burritos in New York",
"address": {
"street": "230 W 4th St",
"city": "New York",
"state": "NY",
"zip": "10014"
},
"location": [
40.7543385,
-73.976313
],
"tags": [
"mexican",
"tacos",
"burritos"
],
"rating": "4.3"
}
还有synonyms.txt
中的内容:
ny, new york, big apple
当我尝试在 address.state
属性 中搜索任何内容时,我得到了 empty
个结果。
查询如下:
{
"query": {
"bool": {
"filter": {
"range": {
"rating": {
"gte": 4
}
}
},
"must": {
"match": {
"address.state": "ny"
}
}
}
}
}
即使用ny
(作为is:no的同义词)查询,结果也是空的。
之前,当我在没有 mappings
的情况下创建索引时,查询用于给出结果,仅同义词除外。
但现在使用 mappings
,即使该术语存在,结果也是空的。
虽然此查询有效:
{
"query":{
"query_string":{
"query": "tacos",
"fields": [
"tags"
]
}
}
}
我查看并研究了许多 articles/tutorials 并得出了这个结论。
我现在在这里缺少什么?
在编制索引时,您将值作为 "state":"NY"
传递。注意 NY
的情况。设置中定义的分析器 synonym
只有一个过滤器,即 synonym
。由于大小写原因,NY
与 synonym.txt 中定义的任何同义词集都不匹配。注意 NY
不等于 ny
。为了克服这个问题(或者我们可以称之为不区分大小写)在 synonym
过滤器之前添加 lowercase
过滤器到 synonym
分析器。这将确保首先将任何输入文本小写,然后应用同义词过滤器。当您使用全文搜索查询在该字段上搜索时,也会发生同样的情况。
所以你的设置如下:
"settings": {
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "whitespace",
"filter": [
"lowercase",
"synonym"
]
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
}
}
}
}
映射中不需要更改。
为什么最初有效?
答案是因为当您没有定义任何映射时,elastic 会将 address.state
映射为 text
字段,而没有为该字段定义明确的分析器。在这种情况下,elasticsearch 默认使用 standard analyzer,它使用小写标记过滤器作为过滤器之一。因此查询与文档匹配。
我正在使用 elasticsearch 7.0.0
。
我在创建 index
时尝试使用此配置处理 synonyms
。
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "whitespace",
"filter": [
"synonym"
]
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
}
}
}
},
"mappings": {
"properties": {
"address.state": {
"type": "text",
"analyzer": "synonym"
},
"location": {
"type": "geo_point"
}
}
}
}
这是插入索引的文档:
{
"name": "Berry's Burritos",
"description": "Best burritos in New York",
"address": {
"street": "230 W 4th St",
"city": "New York",
"state": "NY",
"zip": "10014"
},
"location": [
40.7543385,
-73.976313
],
"tags": [
"mexican",
"tacos",
"burritos"
],
"rating": "4.3"
}
还有synonyms.txt
中的内容:
ny, new york, big apple
当我尝试在 address.state
属性 中搜索任何内容时,我得到了 empty
个结果。
查询如下:
{
"query": {
"bool": {
"filter": {
"range": {
"rating": {
"gte": 4
}
}
},
"must": {
"match": {
"address.state": "ny"
}
}
}
}
}
即使用ny
(作为is:no的同义词)查询,结果也是空的。
之前,当我在没有 mappings
的情况下创建索引时,查询用于给出结果,仅同义词除外。
但现在使用 mappings
,即使该术语存在,结果也是空的。
虽然此查询有效: { "query":{ "query_string":{ "query": "tacos", "fields": [ "tags" ] } } }
我查看并研究了许多 articles/tutorials 并得出了这个结论。
我现在在这里缺少什么?
在编制索引时,您将值作为 "state":"NY"
传递。注意 NY
的情况。设置中定义的分析器 synonym
只有一个过滤器,即 synonym
。由于大小写原因,NY
与 synonym.txt 中定义的任何同义词集都不匹配。注意 NY
不等于 ny
。为了克服这个问题(或者我们可以称之为不区分大小写)在 synonym
过滤器之前添加 lowercase
过滤器到 synonym
分析器。这将确保首先将任何输入文本小写,然后应用同义词过滤器。当您使用全文搜索查询在该字段上搜索时,也会发生同样的情况。
所以你的设置如下:
"settings": {
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "whitespace",
"filter": [
"lowercase",
"synonym"
]
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
}
}
}
}
映射中不需要更改。
为什么最初有效?
答案是因为当您没有定义任何映射时,elastic 会将 address.state
映射为 text
字段,而没有为该字段定义明确的分析器。在这种情况下,elasticsearch 默认使用 standard analyzer,它使用小写标记过滤器作为过滤器之一。因此查询与文档匹配。