Сортировка скриптом в nested объектах


#1

Добрый день!
Стоит задача отсортировать товары по сумме включая ндс, но по одной валюте.
У товара может быть несколько цен, одна цена - одна валюта. При этом у товара может не быть нужной валюты, в таком случа у товара цена должна быть 0.

Настройки индекса и запрос
PUT my_index
{
"mappings": {
    "_doc": {
      "properties": {
        "product": {
          "properties": {
            "vat": {
              "properties": {
                "id": {
                  "type": "long"
                },
                "percent": {
                  "type": "double"
                }
              }
            },
            "prices": {
              "type": "nested",
              "properties": {
                "currency_id": {
                  "type": "long"
                },
                "position": {
                  "type": "long"
                },
                "price": {
                  "type": "double"
                },
                "product_id": {
                  "type": "long"
                }
              }
            }
          }
        }
      }
    }
  }
}

PUT my_index/_doc/1
{
  "product": {
    "vat" : {
      "id" : 1,
      "percent" : 10
    },
    "prices": [
      {
        "product_id": 1,
        "currency_id": 39,
        "price": 2081,
        "position": 0
      },
      {
        "product_id": 1,
        "currency_id": 9,
        "price": 1021,
        "position": 1
      }
    ]
  }
}

PUT my_index/_doc/2
{
  "product": {
    "vat" : {
      "id" : 1,
      "percent" : 20
    },
    "prices": [
      {
        "product_id": 2,
        "currency_id": 39,
        "price": 100,
        "position": 0
      },
      {
        "product_id": 2,
        "currency_id": 9,
        "price": 200,
        "position": 1
      }
    ]
  }
}

PUT my_index/_doc/3
{
  "product": {
    "vat" : {
      "id" : 1,
      "percent" : 15
    },
    "prices": [
      {
        "product_id": 2,
        "currency_id": 19,
        "price": 500,
        "position": 0
      }
    ]
  }
}

GET my_index/_search
{
  "sort": {
    "_script" : {
      "type":"string",
      "order" : "desc",
      "nested" : {
        "path" : "product.prices",
        "filter" : {
          "term" : {
            "product.prices.currency_id": 39
          }
        } 
      },
      "script" : {
        "source" : """
        def price = doc['product.prices.price'].value;
        def vat       = doc['product.vat.percent'].value; 
        
        Debug.explain([price, vat]);

        return price + (price*vat/100);
        
        """
      }
    }
  }
}

Из за nested запроса в сортировке не могу достучаться до ндс товара.
Если убрать nested запрос, то не могу достучаться до цен.

Как получить доступ к нужным данным ?

Ещё вопрос, если в сортировке поставить type=number, то результат документов которых исключил фильтр будет 1.7976931348623157e+308, эти документы не попадают под скрипт что бы установить им 0, параметр missing не доступен если используются скрипты. Как в таком случае устанавливать значение ?


(Igor Motov) #2

А сколько у Вас этих разных валют в системе ожидается?


#3

Общее кол-во валют 50, но не все из них используются. Сейчас используется 9 валют, остальные по мере необходимости будут "включаться" для пользования.


(Igor Motov) #4

Я бы, наверное, не стал делать этот как nested. Я думаю, что-то типа

{
  "product": {
    "prices": {
      "eur": {
        "price": 100,
        "price_with_vat": 110
      },
      "gpd": {
        "price": 200,
        "price_with_vat": 220
      }
    }
  }
}

Будет гораздо эффективнее и проще.


#5

Спасибо, примерно так и сделал.
То что у меня не получалось, это такая особенность или я что-то не правильно делал ?


(Igor Motov) #6

С nested все не так просто. Если в документе есть nested объекты, то эти объекты индексируются как отдельные скрытые документы, и когда скрипт запускается, то в зависимости от типа скрипта, он видит либо основной документ, либо этот скрытый nested документ. В вашем случае скрипт работал на родительском документе.