簡體   English   中英

Elasticsearch 查詢過濾器嵌套數組范圍最小值

[英]Elasticsearch query filter nested array range min

鑒於這些文件:

{
  "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,因為我希望過濾器邏輯只應用於最低價格。

我已經設法使用“mode”:“min”按順序執行此操作,過濾是否有類似的東西?

由於您在過濾最小值時不知道您不知道什么,理論上您可以提出一個查詢時腳本來為您計算。 但這將是繁重低效的。

相反,我建議在攝取時間之前/期間計算局部最小值,這將大大加快查找時間。

您或多或少有 3 個選項:

  1. 使用_update_by_query腳本將頂級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. 使用相同的腳本,但在攝取管道中。 它可以在您即將首次提取文檔以及更新單個文檔時應用(無論出於何種原因)。

  2. 使用我在此處解釋copy_to映射參數 但是您仍然需要一個查詢時腳本來計算局部最小值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM