Elasticsearch查询过滤器嵌套数组范围min

xmakbtuz  于 7个月前  发布在  ElasticSearch
关注(0)|答案(1)|浏览(91)

鉴于这些文件:

{
  "id": "1"
  "prices": [
    {
      "param1": "A",
      "param2": "B",
      "total": 100 
    },
    {
      "param1": "A",
      "param2": "C",
      "total": 200 
    }
  ]
},
{
  "id": "2"
  "prices": [
    {
      "param1": "A",
      "param2": "B",
      "total": 200 
    },
    {
      "param1": "A",
      "param2": "C",
      "total": 300 
    }
  ]
},

字符串
它们如何被价格范围过滤,只有它们的最小总值?
现在我的查询看起来像:

{
  ...
  "query": {
    "bool": {
      "filter": [
        {
          "nested": {
            "path": "prices",
            "query": {
              "bool": {
                "filter": [
                  {
                    "range": {
                      "prices.total": {
                        "gte": 200,
                        "lte": 300
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}


所以它逻辑上返回文档1和2,因为它们的价格都在这个范围内,但我只想得到文档2,因为我希望过滤器逻辑只应用于最低价格。
我已经设法做到这一点,在排序与“模式”:“分钟”,有类似的过滤?

webghufk

webghufk1#

由于在筛选最小值时,您不知道自己不知道的内容,因此理论上可以使用查询时脚本来计算这些内容,但这将是onerousinefficient
相反,我建议在摄取之前/摄取时计算本地最小值,这将大大加快查找时间。

您有3个或多或少的选项:

1.使用_update_by_query script将顶级minTotalPrice分配给所有文档:

POST prices/_update_by_query
{
  "query": {
    "match_all": {}
  },
  "script": {
    "source": """
    def allTotals = ctx._source.prices.stream().map(group -> group.total).collect(Collectors.toList());
    ctx._source.minTotalPrice = Collections.min(allTotals)
    """,
    "lang": "painless"
  }
}

字符串
这大大简化了实际的范围查询:

GET prices/_search
{
  "query": {
    "range": {
      "minTotalPrice": {
        "gte": 200,
        "lte": 300
      }
    }
  }
}


1.使用相同的脚本,但在ingest pipeline中。它可以应用于当你第一次摄取文档以及当你是updating an individual document(无论出于何种原因)。
1.使用copy_to mapping parameter作为I explained here。但是你仍然需要query-time script来计算局部最小值。

相关问题