I have an index that stores ecommerce products. One product has lots of variants, which store the variants' price. The price is also a nested object, as it stores the price along with a date_since variable to indicate when that price started or will start applying to the variant. Here is a basic example:
{
"product_id": "123",
"product_variants":[
{
"variant_id": "456",
"variant_prices":[
{
"price": 100,
"date_since": 1708439263876282,
"date_created": 1708439263876282
},
{
"price": 90,
"date_since": 1708517400328610,
"date_created": 1708517400328610
}
]
},
{
"variant_id": "789",
"variant_prices": [
{
"price": 90,
"date_since": 1708439263876282,
"date_created": 1708439263876282
},
{
"price": 83,
"date_since": 1708517400328610,
"date_created": 1708517400328610
}
]
}
]
}
The challenge is to filter products by price, where the price is defined as the variant_prices.price with it's respective date_since most recent, but in the past. I need to also get inner_hits ideally, indicating which product variants caused the document hit. Is this even possible?
So I can't index the current_price, as it depends on when you are asking. (Maybe there are future prices and in a couple of minutes the filter will not return the same products)
I have tried the following query:
GET /products_with_variants/_search
{
"size": 10,
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"lang": "painless",
"source": """
for (item in params['_source']['product_variants']){
long price = 0;
long date_since = 0;
long date_created = 0;
for(item2 in item["variant_prices"]) {
if (item2["date_since"] > date_since) {
date_since = item2["date_since"];
price = item2["price"];
date_created = item2["date_created"];
}
if (item2["date_since"] == date_since && item2["date_created"] > date_created) {
date_since = item2["date_since"];
price = item2["price"];
date_created = item2["date_created"];
}
}
if (price >= params.priceMin){
return true;
}
}
return false;
""",
"params": {
"priceMin": 10000
}
}
}
}
]
}
}
}
In response, I have gotten:
{
...
"script_stack": [
"for (item in params['_source']['product_variants']){\r\n long ",
" ^---- HERE"
],
...
"caused_by": {
"type": "null_pointer_exception",
"reason": "Cannot invoke \"Object.getClass()\" because \"callArgs[0]\" is null"
}
}
I have also tried iterating trough doc["product_variants"] and params._source.product_variants with no success.
Any help is greatly appreciated!
There is a missing semicolon here:
And as I understood, you are trying to reach a document which is a null. Maybe it would be better to write an if statement to make a null check right after for loops.