我将数据存储在弹性文件中,其中包含year_start和year_end整数值。
然后,我使用“年份”来查询元素。
我的目标是搜索“一年”内的元素。
当我需要搜索该范围内的“年份”中的元素时,我可以使用:
{
"query": {
"bool": {
"filter": [
{
"range": {
"year_start": {
"lte": year
}
}
},
{
"range": {
"year_end": {
"gte": year
}
}
}
]
}
}
但是,我无法获取不在该范围内的元素。我试过这个:
{
"query": {
"must_not": {
"filter": [
{
"range": {
"year_start": {
"lte": year
}
}
},
{
"range": {
"year_end": {
"gte": year
}
}
}
]
}
}
我的quessing是它分别过滤这两个条件,并且它没有同时使用这两个条件。就像“首先我排除一年中的所有内容,然后排除一年中的所有内容”,而不是预期的“排除同时匹配两个条件的每个元素”。
这里有几个可能的解决方案。如果将范围边界存储为单独的字段,则可以使用范围查询:
DELETE test
PUT test/_bulk?refresh
{"index": {}}
{"year_start": "2022", "year_end": "2022" }
{"index": {}}
{"year_start": "2023", "year_end": "2024" }
{"index": {}}
{"year_start": "2021", "year_end": "2025" }
{"index": {}}
{"year_start": "2016", "year_end": "2020" }
# All ranges that include 2022
GET test/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"year_start": {
"lte": 2022
}
}
},
{
"range": {
"year_end": {
"gte": 2022
}
}
}
]
}
}
}
# All ranges that don't include 2022
GET test/_search
{
"query": {
"bool": {
"should": [
{
"range": {
"year_start": {
"gt": 2022
}
}
},
{
"range": {
"year_end": {
"lt": 2022
}
}
}
]
}
}
}
存储和搜索范围的另一种解决方案是使用范围类型:
DELETE test
PUT test
{
"mappings": {
"properties": {
"year_range": {
"type": "integer_range"
}
}
}
}
PUT test/_bulk?refresh
{"index": {}}
{"year_range":{ "gte": "2022", "lte": "2022" }}
{"index": {}}
{"year_range":{ "gte": "2023", "lte": "2024" }}
{"index": {}}
{"year_range":{ "gte": "2021", "lte": "2025" }}
{"index": {}}
{"year_range":{ "gte": "2016", "lte": "2020" }}
# All ranges that include 2022
GET test/_search
{
"query": {
"term" : {
"year_range" : {
"value": 2022
}
}
}
}
# All ranges that don't include 2022
GET test/_search
{
"query": {
"bool": {
"must_not": [
{
"term": {
"year_range": {
"value": 2022
}
}
}
]
}
}
}