sorting - 如果在范围内,则按不同字段进行条件ElasticSearch排序

标签 sorting elasticsearch

我确实有产品,并且其中某些产品在特定日期范围内降低了价格。
(简化)示例产品:

{
  "id": 1,
  "price": 2.0,
  "specialPrice": {
    "fromDate": null,
    "tillDate": null,
    "value": 0,
  },
},
{
  "id": 2,
  "price": 4.0,
  "specialPrice": {
    "fromDate": 1540332000,
    "tillDate": 1571781600,
    "value": 2.5,
  },
},
{
  "id": 3,
  "price": 3.0,
  "specialPrice": {
    "fromDate": null,
    "tillDate": null,
    "value": 0,
  },
}

按价格过滤没有问题。我可以用一个简单的 bool(boolean) 查询来做。

但是我还没有找到一个可以为我指明正确方向的ElasticSearch脚本的好例子,即使它很简单,只要您知道语法。

我的伪代码:price = ('now' between specialPrice.fromDate and specialPrice.tillDate) ? specialPrice.value : price
有没有一种方法可以将其转换为可以在ElasticSearch排序中使用的内容?

为了进一步说明:默认情况下,所有产品已经按几种条件进行了排序。用户还可以搜索任何术语并过滤结果,同时还可以选择多个排序参数。例如,可以先按标签对项目进行排序,然后再按价格对项目进行排序,它们都是非常动态的,并且以后仍会按其他一些属性(包括_score)对结果进行排序。
因此,仅更改_score会很不好,因为已经进行了复杂的计算以显示给定搜索词的最佳结果。

这是我当前的脚本,在第一个params.currentDate时确实失败了:
"sort": {
"_script": {
  "type": "number",
  "script": {
    "source": "if(doc['specialPrice.tillDate'] > params.currentDate) {params.currentPrice = doc['specialPrice.value']} return params.currentPrice",
    "params": {
      "currentDate": "now",
      "currentPrice": "doc['price']"
    }
  }
}

现在如何工作:
一个问题是一些属性的嵌套。
因此,我的步骤之一就是将其内容复制到产品的新字段中(我对此并不满意,但无论如何)。
因此,在映射中,我为产品创建了新属性(specialFrom,specialTill,specialValue),并使用新的属性名称在我的specialPrice“copy_to”属性中提供了相应的字段。
该部分使用php数组语法,因为我使用的是ruflin / elastica:
            'specialPrice' => [
                'type' => 'nested',
                'properties' => [
                    'fromDate' => [
                        'type' => 'date',
                        'format' => 'epoch_second',
                        'copy_to' => 'specialFrom',
                    ],
                    'tillDate' => [
                        'type' => 'date',
                        'format' => 'epoch_second',
                        'copy_to' => 'specialTill',
                    ],
                    'value' => [
                        'type' => 'float',
                        'copy_to' => 'specialValue',
                    ],
                ],
            ],
            'specialFrom' => [
                'type' => 'date',
                'format' => 'epoch_second',
            ],
            'specialTill' => [
                'type' => 'date',
                'format' => 'epoch_second',
            ],
            'specialValue' => [
                'type' => 'float',
            ],

现在我的排序排序脚本看起来确实是这样的(在我的测试客户端中,仍在elastica中实现它):
"sort": {
"_script": {
  "type": "number",
  "script": {
    "lang": "painless",
    "source": "params.param = ((doc['specialTill'].value - new Date().getTime()) > 0 && (new Date().getTime() - doc['specialFrom'].value) > 0) ? doc['specialValue'].value : doc['price'].value; return params.param;",
    "params": {
      "param": 0.0
    }
  }
}

}

我对此不满意,因为我有冗余的数据和脚本(在脚本中两次调用new Date().getTime()),但是它确实有效,这是目前最重要的事情:)

最佳答案

我已经更新了以下查询,请您澄清一下。让我知道是否可行!

POST dateindex/_search
{  
   "query":{  
      "match_all":{  // you can ignore this, I used this to test at my end

      }
   },
   "sort":{  
      "_script":{  
         "type":"number",
         "script":{  
            "lang":"painless",
            "inline":" params.param = ((doc['specialPrice.tillDate'].value - new Date().getTime()) > 0) ? doc['specialPrice.value'].value : doc['price'].value; return params.param;",
            "params":{  
               "param":0.0
            }
         },
         "order":"asc"
      }
   }
}

您可以在上面的查询中尝试使用source代替inline,因为我已经在计算机上测试ES5.X版本。

希望能帮助到你!

关于sorting - 如果在范围内,则按不同字段进行条件ElasticSearch排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52985288/

相关文章:

javascript - 根据属性重新排序对象数组

mysql - 在 MySQL 中通过复杂表达式获取 N 行顺序的有效方法

linux - Logstash 文件限制?

elasticsearch - Elasticsearch:如何允许多语言搜索?

c# - 如何模拟IElasticClient的Get方法?

c++ - 通过字节比较对结构进行排序的最佳排序算法?

javascript - 根据 Javascript 中的条件过滤、排序和映射数组

arrays - 计算反转次数以查看数组是否部分排序

elasticsearch - Kibana中的垂直条形图

elasticsearch - kafka avro elasticsearch消费者允许未知键