My use case is something similar to following.
I have nested array of objects warehouses
and trying to filter based on the last element of the array.
I am getting some results but not correct one. Like to know how exactly it is working though as well.
Let's say,
I want to search for a product based on stocks last element of warehouse array. This is the product document looks like:
{
"productId": 5,
"productName": "Shoes",
"warehouses": [
{
"location": "Location A",
"quantity": 100
},
{
"location": "Location B",
"quantity": 10
},
{
"location": "Location C",
"quantity": 50
}
]
}
And it's mapping is :
PUT /products
{
"mappings": {
"properties": {
"productId": {
"type": "integer"
},
"productName": {
"type": "text",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
},
"warehouses": {
"properties": {
"location": {
"type": "text"
},
"quantity": {
"type": "integer"
}
}
}
}
}
}
Let's say, I index following 7 documents:
POST products/_bulk
{"index":{"_id":1}}
{"productId":1,"productName":"Bags","warehouses":[{"location":"Location A","quantity":20},{"location":"Location B","quantity":30},{"location":"Location C","quantity":50}]}
{"index":{"_id":2}}
{"productId":2,"productName":"Shirts","warehouses":[{"location":"Location A","quantity":100},{"location":"Location B","quantity":150},{"location":"Location C","quantity":150}]}
{"index":{"_id":3}}
{"productId":3,"productName":"Shoes","warehouses":[{"location":"Location A","quantity":100},{"location":"Location B","quantity":10},{"location":"Location C","quantity":50}]}
{"index":{"_id":4}}
{"productId":4,"productName":"Shirt","warehouses":[{"location":"Location A","quantity":100},{"location":"Location B","quantity":10},{"location":"Location C","quantity":60}, {"location":"Location F","quantity":70}]}
{"index":{"_id":5}}
{"productId":5,"productName":"Socks","warehouses":[{"location":"Location A","quantity":800},{"location":"Location B","quantity":1500},{"location":"Location Z","quantity":1000}]}
{"index":{"_id":6}}
{"productId":6,"productName":"TV","warehouses":[{"location":"Location A","quantity":20},{"location":"Location B","quantity":150},{"location":"Location C","quantity":123}]}
{"index":{"_id":7}}
{"productId":7,"productName":"Table","warehouses":[{"location":"Location A","quantity":20},{"location":"Location B","quantity":200},{"location":"Location C","quantity":140}, {"location":"Location D","quantity":123}]}
Now I would like to search and filter products with "quantity": 123. So as per above indexed documents, I suppose to filter and get the products with id:6 and id:7, because it has the quantity: 123 as its last element.
Here is my Painless(full) script:
GET /products/_search
{
"query": {
"bool": {
"must": {
"match_all": {}
},
"filter": {
"bool": {
"must": {
"script": {
"script": {
"lang": "painless",
"source": """
def x = doc['warehouses.quantity'];
def flag = false;
if(x[x.length - 2 ] == params.limit) {
flag = true;
}
return flag;
""",
"params": {
"limit": 123
}
}
}
}
}
}
}
}
}
So in above script I get result for id:6
which is TV product.
And when I replace x[x.length - 2 ]
with x[x.length - 3 ]
I can get result for id:7
.
I am not sure how to get result which contains both documents, [id:6 (TV) and id:7 (Table)].
I am using Elasticsearch version: 7.8.1.