如何让elasticsearch更加灵活?
How to make elastic search more flexible?
我目前正在使用这个 elasticsearch DSL 查询:
{
"_source": [
"title",
"bench",
"id_",
"court",
"date"
],
"size": 15,
"from": 0,
"query": {
"bool": {
"must": {
"multi_match": {
"query": "i r coelho",
"fields": [
"title",
"content"
]
}
},
"filter": [],
"should": {
"multi_match": {
"query": "i r coelho",
"fields": [
"title.standard^16",
"content.standard"
]
}
}
}
},
"highlight": {
"pre_tags": [
"<tag1>"
],
"post_tags": [
"</tag1>"
],
"fields": {
"content": {}
}
}
}
这是正在发生的事情。如果我搜索 I.r coelho
它 returns 正确的结果。但是,如果我搜索 I R coelho
(没有句点),那么它会 returns 一个不同的结果。我如何防止这种情况发生?我希望搜索行为相同,即使有额外的句点、空格、逗号等。
映射
{
"courts_2": {
"mappings": {
"properties": {
"author": {
"type": "text",
"analyzer": "my_analyzer"
},
"bench": {
"type": "text",
"analyzer": "my_analyzer"
},
"citation": {
"type": "text"
},
"content": {
"type": "text",
"fields": {
"standard": {
"type": "text"
}
},
"analyzer": "my_analyzer"
},
"court": {
"type": "text"
},
"date": {
"type": "text"
},
"id_": {
"type": "text"
},
"title": {
"type": "text",
"fields": {
"standard": {
"type": "text"
}
},
"analyzer": "my_analyzer"
},
"verdict": {
"type": "text"
}
}
}
}
}
设置:
{
"courts_2": {
"settings": {
"index": {
"highlight": {
"max_analyzed_offset": "19000000"
},
"number_of_shards": "5",
"provided_name": "courts_2",
"creation_date": "1581094116992",
"analysis": {
"filter": {
"my_metaphone": {
"replace": "true",
"type": "phonetic",
"encoder": "metaphone"
}
},
"analyzer": {
"my_analyzer": {
"filter": [
"lowercase",
"my_metaphone"
],
"tokenizer": "standard"
}
}
},
"number_of_replicas": "1",
"uuid": "MZSecLIVQy6jiI6YmqOGLg",
"version": {
"created": "7010199"
}
}
}
}
}
编辑
以下是 I.R coelho
来自 my analyzer
- {
"tokens": [
{
"token": "IR",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "KLH",
"start_offset": 4,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 1
}
]
}
的结果
标准分析仪:
{
"tokens": [
{
"token": "i.r",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "coelho",
"start_offset": 4,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 1
}
]
}
你在搜索 I.r coelho
和 I R coelho
时有不同行为的原因是你在相同的字段上使用不同的分析器,即 my_analyzer
搜索 [=13] =] 和 content
(must
块),standard
(默认值)用于 title.standard
和 content.standard
(should
块)。
两个分析器生成不同的标记,因此当您搜索 I.r coelho
(例如,使用标准分析器的 2 个标记)或 I R coelho
(例如,使用标准的分析器搜索 3 个标记)时,会确定不同的分数标准分析仪)。您可以使用 analyze
API(请参阅 Elastic Documentation)来测试分析器的行为。
你必须决定这是否是你想要的行为。
更新(在请求 OP 澄清之后)
_analyze
查询的结果证实了假设:两个分析器导致不同的分数贡献,并且随后根据您的查询是否包含符号字符而产生不同的结果。
如果您不希望查询结果受到点或 upper/lower 大小写等符号的影响,则需要重新考虑要应用的分析器。当前使用的永远无法满足您的要求。如果我正确理解了您的要求,那么 simple
built-in analyzer 应该适合您的用例。
简而言之,(1) 您应该考虑将 standard
内置分析器替换为 simple
分析器,(2) 您应该决定是否希望您的查询应用不同的根据不同的分析器(即 title
和 content
字段的值的语音自定义,以及各自子字段的 simple
的值对匹配项进行评分。
我目前正在使用这个 elasticsearch DSL 查询:
{
"_source": [
"title",
"bench",
"id_",
"court",
"date"
],
"size": 15,
"from": 0,
"query": {
"bool": {
"must": {
"multi_match": {
"query": "i r coelho",
"fields": [
"title",
"content"
]
}
},
"filter": [],
"should": {
"multi_match": {
"query": "i r coelho",
"fields": [
"title.standard^16",
"content.standard"
]
}
}
}
},
"highlight": {
"pre_tags": [
"<tag1>"
],
"post_tags": [
"</tag1>"
],
"fields": {
"content": {}
}
}
}
这是正在发生的事情。如果我搜索 I.r coelho
它 returns 正确的结果。但是,如果我搜索 I R coelho
(没有句点),那么它会 returns 一个不同的结果。我如何防止这种情况发生?我希望搜索行为相同,即使有额外的句点、空格、逗号等。
映射
{
"courts_2": {
"mappings": {
"properties": {
"author": {
"type": "text",
"analyzer": "my_analyzer"
},
"bench": {
"type": "text",
"analyzer": "my_analyzer"
},
"citation": {
"type": "text"
},
"content": {
"type": "text",
"fields": {
"standard": {
"type": "text"
}
},
"analyzer": "my_analyzer"
},
"court": {
"type": "text"
},
"date": {
"type": "text"
},
"id_": {
"type": "text"
},
"title": {
"type": "text",
"fields": {
"standard": {
"type": "text"
}
},
"analyzer": "my_analyzer"
},
"verdict": {
"type": "text"
}
}
}
}
}
设置:
{
"courts_2": {
"settings": {
"index": {
"highlight": {
"max_analyzed_offset": "19000000"
},
"number_of_shards": "5",
"provided_name": "courts_2",
"creation_date": "1581094116992",
"analysis": {
"filter": {
"my_metaphone": {
"replace": "true",
"type": "phonetic",
"encoder": "metaphone"
}
},
"analyzer": {
"my_analyzer": {
"filter": [
"lowercase",
"my_metaphone"
],
"tokenizer": "standard"
}
}
},
"number_of_replicas": "1",
"uuid": "MZSecLIVQy6jiI6YmqOGLg",
"version": {
"created": "7010199"
}
}
}
}
}
编辑
以下是 I.R coelho
来自 my analyzer
- {
"tokens": [
{
"token": "IR",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "KLH",
"start_offset": 4,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 1
}
]
}
标准分析仪:
{
"tokens": [
{
"token": "i.r",
"start_offset": 0,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "coelho",
"start_offset": 4,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 1
}
]
}
你在搜索 I.r coelho
和 I R coelho
时有不同行为的原因是你在相同的字段上使用不同的分析器,即 my_analyzer
搜索 [=13] =] 和 content
(must
块),standard
(默认值)用于 title.standard
和 content.standard
(should
块)。
两个分析器生成不同的标记,因此当您搜索 I.r coelho
(例如,使用标准分析器的 2 个标记)或 I R coelho
(例如,使用标准的分析器搜索 3 个标记)时,会确定不同的分数标准分析仪)。您可以使用 analyze
API(请参阅 Elastic Documentation)来测试分析器的行为。
你必须决定这是否是你想要的行为。
更新(在请求 OP 澄清之后)
_analyze
查询的结果证实了假设:两个分析器导致不同的分数贡献,并且随后根据您的查询是否包含符号字符而产生不同的结果。
如果您不希望查询结果受到点或 upper/lower 大小写等符号的影响,则需要重新考虑要应用的分析器。当前使用的永远无法满足您的要求。如果我正确理解了您的要求,那么 simple
built-in analyzer 应该适合您的用例。
简而言之,(1) 您应该考虑将 standard
内置分析器替换为 simple
分析器,(2) 您应该决定是否希望您的查询应用不同的根据不同的分析器(即 title
和 content
字段的值的语音自定义,以及各自子字段的 simple
的值对匹配项进行评分。