从第一个数组元素访问值-过滤

时间:2018-12-17 11:16:25

标签: elasticsearch

度过了一个周末寻找答案后,我决定向您寻求帮助。我有产品索引。变量是产品中对象的嵌套列表,我在进料索引时按库存数量和其他一些条件对其进行排序。 我正在尝试按弹性resposne中的第一个变量值对产品进行排序(包括在查询中传递的过滤器)。这是我正在寻找的示例。 缩短的弹性响应结构:

{
    "id": 6346,
    "name": "name",
    "variants": [
        {
            "variant_id": 1,
            "stock_quantity": 20,
            "price": 9.9
        },
        {
            "variant_id": 2,
            "stock_quantity": 15,
            "price": 20.9
        },
        {
            "variant_id": 3,
            "stock_quantity": 0,
            "price": 16.9
        }
    ]
}

让我们按价格gte 15筛选列表:

{
    "id": 6346,
    "name": "name",
    "variants": [
        {
            "variant_id": 2,
            "stock_quantity": 15,
            "price": 20.9
        },
        {
            "variant_id": 3,
            "stock_quantity": 0,
            "price": 16.9
        }
    ]
}

现在,我尝试根据响应的第一个变体价格对产品进行排序。到目前为止,我尝试做什么?

按脚本排序

"sort": 
     {
       "_script": {
         "order": "desc",
         "type": "number",
         "script": {
          "source": "return params['_source']['variants'][0].gross_price"
         }
       }
     }

一直有效,直到我开始过滤列表。在variants.gross_price gte 15的情况下,脚本从源文档返回值:9.9,而不是我期望的20.9。我忽略了出于性能原因不建议使用ref来源的事实。

按字段排序

"sort": 
{
      "variants.gross_price": {
        "nested": {
          "path": "variants",
          "filter": {
            "bool": {
              "filter": [               
                {
                  "range": {
                    "variants.gross_price": {
                      "gt": "15"
}
[...]

我不知道为什么,但是通过这种方式,我无法从响应中得到第一个变体的价格,而是产品中最便宜的变体的价格-在这种情况下为16.9。

我还向变量中添加了标记'include_in_parent',并尝试通过脚本中的“ doc ['variants.gross_price']。values”获取值,但效果与第一个相同。

所以。我还能尝试做什么?

更新 我正在寻找6.5版本的Max_children。

2 个答案:

答案 0 :(得分:2)

您可以尝试以下脚本。

"sort": {
        "_script": {
            "type": "number",
            "script": {
                "inline": "if(doc['variants.gross_price'].value > 15) {max = doc['variants.gross_price'].value;}, abs(max)",
            "order" : asc
            }
       }
   }

答案 1 :(得分:1)

在这里,请使用java max而不是999,您应该可以;)。您必须在id上循环才能找到总价> 15的分钟。并退还相关的总价。请告诉我们是否可行,我对数据进行了测试,看来还可以。

{
  "query": {
    "nested": {
      "path": "variants",
      "query": {
        "range": {
          "variants.gross_price": {
            "gt": "15"
          }
        }
      }
    }
  },
  "sort": [
    {
      "_script": {
        "script": {
          "inline": " int minima = 999; long result = -1; if (doc['variants.gross_price'].value > 15) { if (doc['variants.variant_id'].value < minima) minima = doc['variants.variant_id'].value; result = doc['variants.gross_price'].value;} \n return result",
          "lang": "painless"
        },
        "order": "desc",
        "nested_path": "variants",
        "type": "number"
      }
    }
  ],
  "from": 0,
  "size": 10
}