I have few documents with array "items" , i want to only pick those documents where "items.name" is equal to "red". If there is any document with one red and another color, then it should not come in result.
1.
{
"items": [
{
"id": "4",
"name": "red"
},
{
"id": "5",
"name": "blue"
}
]
}
{
"items": [
{
"id": "3",
"name": "red"
}
]
}
{
"items": [
{
"id": "2",
"name": "red"
},
{
"id": "1",
"name": "red"
}
]
}
Now, here i need a query where only document 2 and 3 should come in result, as "red" is present in all the "items.name". document 1 is ignored as it contains blue also.
CodePudding user response:
Here is my first solution with the script :
GET test/_search
{
"runtime_mappings": {
"all_red_items": {
"type": "boolean",
"script": {
"source": "int count = 0; for (int i = 0; i < doc['items.name'].size(); i ) { if (doc['items.name'][i] != 'red') { count }} emit(count == 0);"
}
}
},
"query": {
"bool": {
"must": [
{
"term": {
"all_red_items": {
"value": true
}
}
}
]
}
}
}
Here is my regular expression solution :
GET test/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"items.name": {
"value": "red"
}
}
}
],
"must_not": [
{
"regexp": {
"items.name": "@&~(red)"
}
}
]
}
}
}
Before going to send the request, you need to prepare your index below :
DELETE test
PUT test
{
"mappings": {
"properties": {
"items": {
"properties": {
"name": {
"type": "keyword"
}
}
}
}
}
}
POST test/_doc
{
"items": [
{
"id": 6,
"name": "red"
},
{
"id": 5,
"name": "blue"
}
]
}
POST test/_doc
{
"items": [
{
"id": 1,
"name": "red"
}
]
}
POST test/_doc
{
"items": [
{
"id": 3,
"name": "red"
},
{
"id": 4,
"name": "red"
}
]
}
GET test/_mapping