Elasticsearch:搜索范围之外的元素

问题描述 投票:0回答:1

我将数据存储在弹性文件中,其中包含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是它分别过滤这两个条件,并且它没有同时使用这两个条件。就像“首先我排除一年中的所有内容,然后排除一年中的所有内容”,而不是预期的“排除同时匹配两个条件的每个元素”。

elasticsearch dsl
1个回答
0
投票

这里有几个可能的解决方案。如果将范围边界存储为单独的字段,则可以使用范围查询:

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
            }
          }
        }
      ]
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.