我正在尝试查询在特定文本字段Field_Name_1
上具有匹配值的所有文档的索引,并对这些结果进行过滤,以仅显示其Field_Name_2
字段在所提供的列表中具有任意数值的文档。
我面临的问题是,查询将返回与Field_Name_1
中的值有点匹配的文档,但我只需要返回与Field_Name_1
的值完全匹配的文档。通过研究,我认为我应该将Field_Name_1
设置为关键字字段,而不是文本字段,因为我永远不需要通过提供Field_Name_1
的完整值来运行此查询。
我认为我需要创建一个新的索引,并将Field_Name_1
设置为关键字,然后重新建立索引,这是正确的吗?我以前没有重建过索引,所以我担心如果我做得不好会丢失数据。有没有办法在Field_Name_1
为文本字段的情况下执行此查询?
这是我尝试过的两个查询,但它们都返回相同的结果。唯一的区别是第一个查询返回的"max_score“为9.54,而第二个查询返回的"max_score”为0。
GET Index_Name/_search
{
"query": {
"bool": {
"must": {
"match": {
"Field_Name_1": "12345-1234-1234-1234-d123f123g123"
}
},
"filter": {
"terms": {
"Field_Name_2": [
1,
2,
3,
4,
5
]
}
}
}
},
"track_total_hits": true
}
GET Index_Name/_search
{
"query": {
"bool": {
"filter": [
{
"match": {
"Field_Name_1": "12345-1234-1234-1234-d123f123g123"
}
},
{
"terms": {
"Field_Name_2": [
1,
2,
3,
4,
5
]
}
}
]
}
},
"track_total_hits": true
}
发布于 2021-03-16 10:15:41
keyword
字段应为类型。
这是因为如果未指定分析器,则Elasticsearch使用standard analyzer。您可以使用分析API检查生成的令牌,如下所示:
GET /_analyze
{
"analyzer": "standard",
"text": "12345-1234-1234-1234-d123f123g123"
}
生成的令牌将是
{
"tokens": [
{
"token": "12345",
"start_offset": 0,
"end_offset": 5,
"type": "<NUM>",
"position": 0
},
{
"token": "1234",
"start_offset": 6,
"end_offset": 10,
"type": "<NUM>",
"position": 1
},
{
"token": "1234",
"start_offset": 11,
"end_offset": 15,
"type": "<NUM>",
"position": 2
},
{
"token": "1234",
"start_offset": 16,
"end_offset": 20,
"type": "<NUM>",
"position": 3
},
{
"token": "d123f123g123",
"start_offset": 21,
"end_offset": 33,
"type": "<ALPHANUM>",
"position": 4
}
]
}
要返回与Field_Name_1
的值完全匹配的文档,可以将Field_Name_1
字段的数据类型更改为keyword
类型。
修改后的索引映射将是
{
"mappings": {
"properties": {
"Field_Name_1": {
"type": "keyword"
}
}
}
}
或者,如果您尚未显式定义任何映射,则还可以像这样修改搜索查询:
{
"query": {
"bool": {
"must": {
"match": {
"Field_Name_1.keyword": "12345-1234-1234-1234-d123f123g123" // note this
}
},
"filter": {
"terms": {
"Field_Name_2": [
1,
2,
3,
4,
5
]
}
}
}
},
"track_total_hits": true
}
这将使用keyword
分析器而不是标准分析器(请注意Field_Name_1
后的".keyword“字段)
发布于 2021-03-16 12:25:05
我认为ESCoder写的就是你问题的答案。
另外,
“为查询上下文中的查询计算的分数表示为单精度浮点数”
在过滤器上下文 中,不计算任何分数。Filter context主要用于过滤结构化数据,例如Field_Name_1字段是否设置为"12345-1234-1234-1234-d123f123g123"?
“经常使用的过滤器将被Elasticsearch自动缓存,以提高性能。”
如果需要精确匹配Field_Name_1的值,可以使用筛选器作为更好的选择。
https://www.elastic.co/guide/en/elasticsearch/reference/7.11/query-filter-context.html
GET Index_Name/_search
{
"query": {
"bool": {
"filter": [
{
"match": {
"Field_Name_1.keyword": "12345-1234-1234-1234-d123f123g123"
}
},
{
"terms": {
"Field_Name_2": [
1,
2,
3,
4,
5
]
}
}
]
}
},
"track_total_hits": true
}
https://stackoverflow.com/questions/66646914
复制相似问题