У меня есть продукты, и некоторые из них снижены в цене для определенного диапазона дат.(упрощенный) пример продукции:
{
"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.
Но я пока не смог найти хороший пример сценариев 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 /astica:
'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',
],
Теперь мой скрипт сортировки сортировки выглядит следующим образом (в моем тестирующем клиенте все еще работаю над его реализацией вastica):
"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
}
}
}
}
Я не на 100% доволен этим, потому что у меня есть избыточные данные и сценарии (дважды вызывая new Date().getTime()
в сценарии), но это работает, и этосамое главное на данный момент:)