How to search by an specific value or where field does not exists in Elasticsearch - elasticsearch

Im trying to do a query where the field does not exists or is in the array of values, in mongo it would be something like this.
$or: [
{
field: {
$exists: false
}
},
{
field: [val1, val2]
}
]
I've tried with a couple of variations but cant seem to find the solution for this.
Edit1:
Basically on my mind, the query should look like.
query: {
"bool": {
"should": [
"must": {...logic}
"must_not": {...logic}
]
}
}
this returns
"must_not" malformed

You need to do it like this:
{
"query": {
"bool": {
"should": [
{
"terms": {
"field": [
"val1",
"val2"
]
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "field"
}
}
}
}
]
}
}
}

Related

Elasticsearch filter by matching query in all nested documents

I have a problem with filtering elastic documents by nested documents.
In general document has a list of nested assets and each asset have a list of teamIds
Sample cut off document:
{
"assets":[
{
"id":100,
"teams":[
1
]
},
{
"id":101,
"teams":[
4,
3
]
}
]
}
Expected result is to get root document where all assets have at least one matching team
I've tried:
{
"from": 0,
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"nested": {
"path": "assets",
"query": {
"terms": {
"assets.teams": [
1
]
}
}
}
}
]
}
},
{
"bool": {
"must_not": [
{
"nested": {
"path": "assets",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "assets"
}
}
]
}
}
}
}
]
}
}
]
}
}
]
}
},
"size": 999
}
Unfortunately this query return document. In this case I do expect it returns document if query contains ids like [1,3], [1,4] or [1,3,4]
Thanks in advance
To find a document where all nested documents contain any of given terms
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "assets",
"query": {
"bool": {
"must_not": [
{
"terms": {
"assets.teams": [
"1"
]
}
}
]
}
}
}
}
]
}
}
}
````
In the above, nested query returns documents where a nested document does not contain any of given term, then outer must_not excludes those documents.
In other words first find documents where a nested document doesnot contain given term and then exclude those documents.
If you want to include documents where teams field is not present use below
````
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "assets",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "assets.teams"
}
}
],
"must_not": [
{
"terms": {
"assets.teams": [
"1"
]
}
}
]
}
}
}
}
]
}
}
}
````

Elasticsearch: Multiple fields, return true if any exists

ES version: 5.2 alpine
I have a document like this:
{
"field1": null,
"field2": "xyz"
"field3": null
}
I want to return the document if any of the fields above exists/not null.
"filter": {
"bool": {
"must": [
{
"exists": {
"field": ["field1","field2"]
}
}]
}
}
but I get following error.
[exists] unknown token [START_ARRAY] after [field]
Any idea how to do so with this ES version?
Thanks.
You cannot pass multiple fields in exists query. Use exists query for each field and wrap them in should clause as below:
{
"query": {
"bool": {
"should": [
{
"exists": {
"field": "field1"
}
},
{
"exists": {
"field": "field2"
}
},
{
"exists": {
"field": "field3"
}
}
]
}
}
}
I am not sure you want to return the doc if field value exist, or also the value. This is for returning documents which satisfies the condition.
This can help,
You can use should query with minimum should match as 1.
"filter": {
"bool": {
"should": [
{ "exists": { "field": "field1 } },
{ "exists": { "field": "field2 } },
],
"minimum_should_match" : 1,
}
}
Try it, I hope it will work in your version as well.

How to combine must and must_not in elasticsearch with same field

i have elasticsearch 6.8.8, just for an example of my question. I want to create a query that gets me document with "Test" field with value "1", and i don't want to get "Test" field with value of "3", i know that i could write just the first expression without 3 and it will give me one document with value of "1". But i want to know, is there any way, that i can use must and must_not in the same time, on the same field and getting just the value of "1"?
I wrote this basic example to know what i mean:
{
"from": 0,
"query": {
"nested": {
"path": "attributes",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "1"
}
}
}
],
"must_not": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "3"
}
}
}
]
}
}
]
}
}
}
}
}
I use attributes as nested field with key-value field that use mapping as string type.
You'll need to leave out attributes.key:Test in the must_not because it filters out all Tests:
GET combine_flat/_search
{
"from": 0,
"query": {
"nested": {
"inner_hits": {},
"path": "attributes",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "1"
}
}
}
],
"must_not": [
{
"match": {
"attributes.value": {
"query": "3"
}
}
}
]
}
}
]
}
}
}
}
}
Tip: use inner_hits to just return the matched nested key-value pairs as opposed to the whole field.

How to filter a specific value within a dictionary?

Let's say I have this dictionary:
{
"name": "Jorje",
"surname": "Costali",
"extra_information": {
"real_name": "mamino",
"fake_name": "bambino",
"age": "43",
"gang": "gang34"
}
}
How can I query to get all entries that have "extra_information.gang":"gang34" ? I would like to know how to filter after exact term or having a match.
I have tried:
{
"size": 20,
"query": {
"bool": {
"filter": [
{
"terms": {
"extra_information.gang": [
"gang34"
]
}
}
]
}
}
}
but it does not return any entries.
I have tried:
GET _search
{
"query": {
"bool": {
"must": [
{
"match": {
"extra_information.gang" : "gang34"
}
}
]
}
}
}
and works, but I want to make it into a filter, not a simple match query.
Did you try to use .keyword? like:
"terms": {
"extra_information.gang.keyword": [
"gang34"
]
}
I tried what you wrote on my nested dictionary document, it works like this to me.

How to write a conditional query with Elasticsearch?

I have a simple JSON query for Elasticsearch that looks like this:
"query": {
"bool": {
"must": { "match": { "id": "1" }} ,
"must": { "match": { "tags.name": "a1"}}
}
}
How can I execute the second 'must' criteria ONLY if the value ('a1' in this case) is not empty?
You can achieve it using the following -
{
"query": {
"bool": {
"must": [
{
"match": {
"id": "1"
}
},
{
"bool": {
"should": [
{
"missing": {
"field": "tags.name"
}
},
{
"match": {
"tags.name": "a1"
}
}
]
}
}
]
}
}
}
I don't think "missing" can be used in the latest versions of elasticsearch.
But one can use Conditional Clauses instead.
https://www.elastic.co/guide/en/elasticsearch/reference/6.3/search-template.html#_conditional_clauses

Resources