Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 条件ElasticSearch按不同字段排序(如果在范围内)_Sorting_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch - Fatal编程技术网 elasticsearch,Sorting,elasticsearch" /> elasticsearch,Sorting,elasticsearch" />

Sorting 条件ElasticSearch按不同字段排序(如果在范围内)

Sorting 条件ElasticSearch按不同字段排序(如果在范围内),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": 1571781

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

{
  "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,
  },
}
按价格过滤没有问题。我可以用一个简单的布尔查询

但是我还没有找到一个ElasticSearch脚本的好例子,它可以为我指明正确的方向,即使它应该非常简单,因为你知道语法

我的伪代码:
price=('now'介于specialPrice.fromDate和specialPrice.tillDate之间)?specialPrice.value:价格

有没有一种方法可以将其转换为在ElasticSearch排序中工作的内容

进一步澄清:默认情况下,所有产品都已按多个条件排序。用户还可以搜索任何术语并过滤结果,同时还可以选择多个排序参数。例如,项目可以按标签排序,然后按价格排序,这都是非常动态的,之后它仍然会按一些其他属性(包括_分数)对结果进行排序。 因此,仅仅改变_分数是不好的,因为这已经是在一个复杂的问题中计算出来的,以显示给定搜索词的最佳结果

这是我当前的脚本,它在第一个
参数时失败。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',
            ],
"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
    }
  }
}
现在,我的排序脚本看起来确实是这样的(在我的测试客户机中,仍在致力于在elastica中实现它):

}


我对此不是100%满意,因为我有多余的数据和脚本(在脚本中调用两次
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
版本


希望有帮助

谢谢,但我不确定这是否真的对我有帮助。我本以为会发生这样的事情:从我对你答案的理解来看,每次我想按价格排序时,我都必须更新我所有产品的价格。这对我来说似乎不是很有效;)我会继续试验的。@FanMake只是想说清楚,你不想更新价格。只需要排序,它应该按照您提供的psuedo代码工作?这是正确的。如果用户选择按价格排序,ElasticSearch应使用“特价”,如果它在当前日期有效,则使用正常价格,否则:)@Fanmake请立即检查我的答案。我已经更新了另一个解决方案。如果有帮助,请告诉我!非常感谢您的帮助和耐心!:D根据你更新的脚本,我最终设法使它与我的数据一起工作,并相应地更新了我的答案。