ElasticSearch nested bool queries - elasticsearch

I'm using ElasticSearch 5.6. I have following JSON document.
{
"cards": [{
"tag_categories": [
{
"is_sensitive": true,
"category": "Users",
"tags": [
{
"is_selected": true,
"name": "user1"
},
{
"is_selected": true,
"name": "user2"
},
{
"is_selected": false,
"name": "user3"
}
]
}
],
"risk": "medium",
"position": 1,
"placement": 4,
"title": "test title",
}, ...]
}
I want to return this document if all the given users names and corresponding is_selected value is true.
This is my query.
{
"_source": {
"excludes": ["cards.pages"]
},
"query": {
"bool": {
"must": [{
"match": {
"_all": "hello world"
}
}],
"filter": [{
"nested": {
"path": "cards.tag_categories.tags",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"match": {
"cards.tag_categories.tags.name": "user2"
}
},
{
"match": {
"cards.tag_categories.tags.is_selected": true
}
}
]
}
},
{
"bool": {
"must": [
{
"match": {
"cards.tag_categories.tags.name": "user1"
}
},
{
"match": {
"cards.tag_categories.tags.is_selected": true
}
}
]
}
}
]
}
}
}
},
{
"term": {
"name.keyword": "hello name"
}
},
{
"term": {
"title.keyword": "hello title"
}
}
]
}
}
}
I have added two child bool queries to match each set of user name and is_selected values. Parent bool query will get the AND and return the document if true.
In the above example query the document should be returned as user1 and user2 match the condition. But it doesn't happen.
If I compare a single user with his is_selected value the document returns. eg: user1.
I will be thankful if anyone can show me where I've made the mistake.

I added separate nested blocks and it worked!
{
"_source": {
"excludes": ["cards.pages"]
},
"query": {
"bool": {
"must": [{
"match": {
"_all": "hello world"
}
}],
"filter": [
{
"nested": {
"path": "cards.tag_categories.tags",
"query": {
"bool": {
"must": [
{
"term": {
"cards.tag_categories.tags.name.keyword": "user1"
}
},
{
"term": {
"cards.tag_categories.tags.is_selected": true
}
}
]
}
}
}
},
{
"nested": {
"path": "cards.tag_categories.tags",
"query": {
"bool": {
"must": [
{
"term": {
"cards.tag_categories.tags.name.keyword": "user2"
}
},
{
"term": {
"cards.tag_categories.tags.is_selected": true
}
}
]
}
}
}
},
{
"term": {
"name.keyword": "hello name"
}
},
{
"term": {
"title.keyword": "hello title"
}
}
]
}
}
}

Related

What can be the query for this statement in Elasticsearch

I am trying to have this query in elasticsearch
statement:
(ip=xx.xx.xx.xx and status="running") or (ip=xx.xx.xx.xx and status="running")
can anyone tell me how can i write this in elasticsearch query.
Read about Bool Queries
Try this query:
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must": [
{
"term": {
"ip": {
"value": "xx.xx.xx.xx"
}
}
},
{
"term": {
"status": {
"value": "running"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"ip": {
"value": "bb.bb.bb.bb"
}
}
},
{
"term": {
"status": {
"value": "running"
}
}
}
]
}
}
]
}
}
}

Issue with ElasticSearch 8.4 query

Hi i have recently been busy reworking our old and outdated ES now um running 8.4 and im trying to create a similar query to what i had in the old one. But i have a hard time finding examples or the right documentation
This is an example what we had on version 1.7:
I have tried te exact same in 8.4 now
{
"index": "vehicles",
"type": "vehicle",
"body": {
"from": "0",
"size": 30,
"query": {
"filtered": {
"query": { "match_all": [] },
"filter": {
"bool": {
"must": [
{
"bool": {
"should": [
[
{ "term": { "make.untouched": "IVECO" } },
{ "term": { "make.untouched": "VOLKSWAGEN" } }
]
]
}
},
{
"bool": {
"should": [[{ "term": { "type_serie.untouched": "DAILY" } }]]
}
},
{
"bool": {
"should": [[{ "term": { "filters.header.camper": "true" } }]]
}
},
{ "range": { "days_sold": { "gte": 0, "lt": 2 } } },
{ "range": { "days_on_stock": { "gte": 3 } } },
{ "range": { "price": { "gt": 0 } } },
{ "range": { "price_trader": { "gt": 0 } } },
{ "term": { "show_in_search": true } }
],
"must_not": [
{ "term": { "offer_code": "z" } },
{ "term": { "stockingtype": "a" } },
{ "term": { "stockingtype": "v" } },
{ "term": { "stockingtype": "z" } },
{ "term": { "stockingtype": "p" } }
]
}
}
}
},
"sort": [
{ "_score": "desc" },
{ "days_on_stock": "asc" },
{ "price": "asc" }
]
}
}
You have double arrays and that's the issue (older versions were more permissive):
"should": [
remove this -->[
{ "term": { "make.untouched": "IVECO" } },
{ "term": { "make.untouched": "VOLKSWAGEN" } }
remove this -->]
]
Same here
same here same here
{ | |
"bool": { v v
"should": [[{ "term": { "type_serie.untouched": "DAILY" } }]]
}
},
{
"bool": {
"should": [[{ "term": { "filters.header.camper": "true" } }]]
}
},

searching elastic search filtering results with and and or conditions

I have an index with the following documents:
{
"first_name": "f1",
"last_name": "l1",
"location": "SF",
"vehicle": {
"type": "car",
"color": "red"
}
}
{
"first_name": "f2",
"last_name": "l2",
"location": "SF",
"vehicle": {
"type": "motorcycle",
"color": "blue"
}
}
{
"first_name": "f3",
"last_name": "l3",
"location": "SF",
"vehicle": {
"type": "bicycle",
"color": "green"
}
}
{
"first_name": "f4",
"last_name": "l4",
"location": "CA",
"vehicle": {
"type": "motorcycle",
"color": "green"
}
}
{
"first_name": "f5",
"last_name": "l5",
"location": "SF"
}
The vehicle document is a nested type.
I would like to filter results:
SELECT WHERE location=SF AND (vehicle.type=car OR
vehicle.type=airplane OR not-exists(vehicle.type)
I could not find a way to do it.
Is there a way to execute such a filter on Elasticsearch?
Thank you.
This query might be helpful.
POST IndexName/Type/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"location": {
"value": "sf"
}
}
},
{
"bool": {
"should": [
{
"terms": {
"vehicle.type": [
"car",
"airplane"
]
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "vehicle.type"
}
}
}
}
]
}
}
]
}
}
}
If you want to search location by case sensitive then use below query. I have used location.keyword for match case sensitive.
POST IndexName/Type/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"location.keyword": {
"value": "SF"
}
}
},
{
"bool": {
"should": [
{
"terms": {
"vehicle.type": [
"car",
"airplane"
]
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "vehicle.type"
}
}
}
}
]
}
}
]
}
}
}
I found a way to do it, it is a bit complex but:
GET indextests/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"location": "SF"
}
},
{
"bool": {
"should": [
{
"nested": {
"path": "vehicle",
"query": {
"terms": {
"vehicle.type": ["car", "bicycle"]
}
}
}
},
{
"bool": {
"must_not": [
{
"nested": {
"path": "vehicle",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"exists": {
"field": "vehicle.type"
}
}
]
}
}
]
}
}
}
}
]
}
}
]
}
}
]
}
}
}

Is it possible to do nested sort with a conditional query on a sort element

we have following structure in an index - following is only a partial and doc relevant for this question.
"instance" : {
"id" : 1,
{"instFields": [
{
"sourceFieldId": 2684,
"fieldValue": "false",
"fieldBoolean": false
},
{
"sourceFieldId": 1736,
"fieldValue": "DODGE",
"fieldString": "DODGE"
},
{
"sourceFieldId": 1560,
"fieldValue": "GRAY",
"fieldString": "GRAY"
},
{
"sourceFieldId": 1558,
"fieldValue": "CHALLENGER",
"fieldString": "CHALLENGER"
},
{
"sourceFieldId": 1556,
"fieldValue": "2010",
"fieldDouble": 2010
}
]
}
first user query is give me all instances where sourceFieldId=1736 - this returns all the DODGE instances[] - all this is working fine with an appripriate Elastic Search query. now when user is seeing all DODGE records - user wants to sort by any of those sourceFieldIds for e.g. say user is wanting to sort results by - color - sourceFieldId=1560.
say we have following sort query
{
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"nested": {
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"instance.dataSourceId": "196"
}
},
{
"term": {
"instance.dsTypeId": "5"
}
},
{
"nested": {
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"instance.instFields.sourceFieldId": "1558"
}
},
{
"term": {
"instance.instFields.fieldString.raw": "challenger"
}
}
]
}
}
}
},
"path": "instance.instFields"
}
}
]
}
}
}
},
"path": "instance",
"inner_hits": {
"name": "inner_data"
}
}
},
{
"nested": {
"query": {
"bool": {
"should": {
"bool": {
"must": [
{
"match": {
"instance.entitlements.roleId": {
"query": "1",
"type": "boolean"
}
}
},
{
"match": {
"instance.entitlements.read": {
"query": "true",
"type": "boolean"
}
}
}
]
}
}
}
},
"path": "instance.entitlements"
}
}
]
}
}
}
},
"sort": {
"instance.instFields.fieldString.raw": {
"order": "asc",
"nested_path": "instance.instFields",
"nested_filter": {
"bool": {
"filter": {
"bool": {
"must": [
{
"nested": {
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"instance.dataSourceId": "196"
}
},
{
"term": {
"instance.dsTypeId": "5"
}
},
{
"nested": {
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"instance.instFields.sourceFieldId": "1558"
}
},
{
"term": {
"instance.instFields.fieldString.raw": "challenger"
}
}
]
}
}
}
},
"path": "instance.instFields"
}
}
]
}
}
}
},
"path": "instance",
"inner_hits": {
"name": "inner_data1"
}
}
},
{
"nested": {
"query": {
"bool": {
"should": {
"bool": {
"must": [
{
"match": {
"instance.entitlements.roleId": {
"query": "1",
"type": "boolean"
}
}
},
{
"match": {
"instance.entitlements.read": {
"query": "true",
"type": "boolean"
}
}
}
]
}
}
}
},
"path": "instance.entitlements"
}
}
]
}
}
}
}
}
}
}
resulting docs must return entire instance with all the soureceFields - as on a user page it displays other values of DODGE as well.
now issue is- sort query still has to have knowledge to sort where - "sourceFieldId": 1560 (which is a sourceFieldId for color) to sort on color
is there a way to achieve such a sort query in ES without using dynamic scripting/dynamic templating? something like
"sort": {
"instance.instFields.fieldString.raw": (where sourceFieldId=1560?)
Should be able to achieve this using nested_filter option in sort
From the documentation:
nested_filter A filter that the inner objects inside the nested path
should match with in order for its field values to be taken into
account by sorting. Common case is to repeat the query / filter inside
the nested filter or query. By default no nested_filter is active.
For example to sort on color field it would be:
{
"sort": {
"instance.instFields.fieldValue.raws": {
"order": "asc",
"nested_path": "instance.instFields",
"nested_filter": {
"term": {
"instance.instFields.sourceFieldId": "1560"
}
}
}
}
}
Edited
"sort": [{
"instance.instFields.fieldValue": {
"order": "asc",
"nested_path": "instance.instFields",
"nested_filter": {
"term": {
"instance.instFields.sourceFieldId": "1560"
}
}
}
},
{
"instance.instFields.fieldValue": {
"order": "asc",
"nested_path": "instance.instFields",
"nested_filter": {
"term": {
"instance.instFields.sourceFieldId": "1558"
}
}
}
}
]

ElasticSearch order by _score

How can I order the results by _score?
I can't figure out how to calculate the score for each result, also :)
I managed to write this:
{
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"term": {
"type_licitatie": "3"
}
},
{
"term": {
"tip_sursa": "5"
}
}
]
}
}
}
},
"sort": [
{
"_score": {
"order": "desc"
}
}
]
}
and this:
{
"query": {
"function_score": {
"query": {
"filtered": {
"filter": {
"bool": {
"should": [
{
"term": {
"country_id": "1"
}
},
{
"term": {
"industry_id": "3"
}
}
]
}
}
}
},
"script_score" : {
"script": "(doc['country_id'].values=1) + (doc['industry_id'].values=3)"
},
"boost_mode": "replace"
}
}
}

Resources