Elastic search combine match and should - elasticsearch

I want to create a query where i can use match, and that match should only consider rows where another field value is null or some specific value.
So something like:
where field1 like 'string' and field2 is null or field2 = 123
Is that possible in JS client?

You can use a combination of bool/must/should along with the exists and wildcard query
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"field1": "string*"
}
},
{
"bool": {
"should": [
{
"term": {
"field2": 123
}
},
{
"bool": {
"must_not": {
"exists": {
"field": "field2"
}
}
}
}
]
}
}
]
}
}
}

Related

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.

Nested boolean query in elasticsearch

I have an sql query like
select student_name,roll_number
from
mytable
where
(course = 'CCNA' or course = 'MCSE') and course NOT Like '%network%'
How can i create an equivalent nested boolean query in elasticsearch?
Below query might help you, This query responds with records which course does not contain a "network" keyword and course has a value "ccna" or "mcse".
I have not considered a case sensitiveness feature here and assumed that you have a default mapping.
POST study-doc*/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"term": {
"course": {
"value": "ccna"
}
}
},{
"term": {
"course": {
"value": "msce"
}
}
}
]
}},
{
"bool": {
"must": [
{
"wildcard": {
"course.keyword": {
"value": "^((?!network).)*$"
}
}
}
]
}
}
]
}
}
}

How to query for empty field or specific value

I'm trying write a query to achieve the following result:
field1: value1 AND
field2: value2 OR "" (empty)
I've tried the following but it always returns me empty results:
{
"_source": ["field1", "field2"],
"query": {
"bool": {
"must": [
{"match": { "field1": "value1" }},
{
"bool": {
"should": [
{
"match": {
"field2": "value2"
}
}
],
"must_not": [
{
"exists": { "field": "field2" }
}
]
}
}
]
}
}
}
I believe I'm making a query that contradicts itself.
This is looking very complicated.
Try using queryStringQuery
Try rewriting your query like this
{
"_source": ["field1", "field2"],
"query": {
"query_string": {
"query": "field1:value1 AND (field2:value2 OR (!field2:*))"
}
}
}
If you still want to use in this format
You have used must_not clause which would mean somewhat this as below according to your use case.
field1: value1 AND
field2: value2 AND NOT "" (empty)
What you should do is
{
"_source": [
"field1",
"field2"
],
"query": {
"bool": {
"must": [
{
"match": {
"field1": "value1"
}
},
{
"bool": {
"should": [
{
"match": {
"field2": "value2"
}
},
{
"bool": {
"must_not": [
{
"exists": {
"field": "field2"
}
}
]
}
}
]
}
}
]
}
}
}
But it would be more easy for you to use queryString if you want to analyze the terms in query first which you have done in your query.
So using queryString OR bool in your this case would be same

Get all docs which not contains the key?

For example,i have 2 type docs,such as
{
"field2":"xx",
"field1","x"
}
{
"field1","x"
}
The one has 2 fields(field1 and field2),another one just has 1 field(field1).
Now,i want to query all docs which do not have field2 field?
EIDT
dsl:
{
"query": {
"bool": {
"filter": [
{
"exists": {
"field": "LableToMember"
}
}
]
}
}
}
doc:
{
"LableToMember": [
{
"xxx": "xxx",
"id": "1"
}
],
"field2":"xxx"
}
LableToMember is a nested field.I find exists api can't be used for nested field?
Note that in ES 5.x the missing query has been removed in favor of the exists one.
So if you want to be forward compatible, you should prefer using this:
POST /_search
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "field2"
}
}
}
}
}
UPDATE
If you want to retrieve all docs which don't have field2 or have field2 with a given value, you can do it like this:
POST /_search
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must_not": {
"exists": {
"field": "field2"
}
}
}
},
{
"term": {
"field2": "somevalue"
}
}
]
}
}
}
In short you want to query those documents which have field2 missing. You can use Missing Query like:
"filter" : {
"missing" : { "field" : "field2" }
}
Hope it helps

elasticsearch query filter "or" with wildcards

I try to use elasticsearch to make a query with wildcard (the use of *) for an autocomplete function.
It was working good with bool query like this (where value can contain *) :
{
"query": {
"bool": {
"must": [
{
"query_string": {
"query": value
}
}
]
}
}
}
But now I want to search only an input value in some fields ( T_FAMILY or T_GENUS or T_SCIENTIFICNAME) and use wildcards $ and *:
{
"fields": [
"T_FAMILY",
"T_GENUS",
"T_SCIENTIFICNAME"
],
"query": {
"filtered": {
"filter": {
"or": [
{
"term": {
"T_FAMILY": value
}
},
{
"term": {
"T_GENUS": value
}
},
{
"term": {
"T_SCIENTIFICNAME": value
}
}
]
}
}
}
}
the query work but the wildcards don't.
I can't find why.
The 3 fields are analyzed in the mapping.

Resources