Elasticsearch bool query must match single field single term, and another field with OR terms - elasticsearch

I want to find a document with a name that contains 'Bob' and has a location that is in either 'paducah' or 'smyrna'.
Here's what I have now:
query: {
bool: {
must: [
{ match: { name: 'bob' } },
{ match: { location: ['paducah', 'smyrna'] } }
],
},
},
I know the problem is in the location array, because if i change it to a single element with no array the query works just fine.
This is the closest answer i could find.
It didn't work, i receive the following error:
[term] malformed query, expected [END_OBJECT] but found [FIELD_NAME]

You could try this query:
{
"query": {
"bool": {
"must": [
{ "match": { "name": "bob" } }
],
"should": [
{ "match": { "location": "paducah" }},
{ "match": { "location": "smyrna" }}
],
"minimum_should_match": 1
}
}
}

What about the following:
{
"query": {
"bool": {
"must": [
{ "term": { "name": "bob" },
"bool": {
"should": [
{"term": {"location": "paducah"}},
{"term": {"location": "smyrna"}}
]
}
}
]
}
}
}

Related

Should as filter context (OR without scoring in Elasticsarch possible?)

I am trying to setup most efficient way to build an OR without having a scoring, since I want to order my results by business values afterwards.
Unfortunately i don't get it done. :(
What I need:
COLOR=X AND ( title = Y OR description = Z)
What I tried (but it is malformed):
{
"query": {
"bool": {
"filter": [
{
"term": {
"colors.source_name": "braun"
}
},
{
"should": [
{
"term": {
"title": "sofa"
}
},
{
"term": {
"description": "sofa"
}
}
]
}
]
}
}
What I also tried, but it also provided results without "gartenlounge", and especially with scoring:
{
"query": {
"bool": {
"filter": [
{
"term": {
"colors.source_name": "braun"
}
}
],
"should": [
{
"term": {
"title": "sofa"
}
},
{
"term": {
"description": "sofa"
}
}
]
}
}
The following query should work for you:
{
"query": {
"bool": {
"filter": [
{"term": {
"colors.source_name": "braun"
}},
{"bool": {
"should": [
{"term": {"title": "sofa"}},
{"term": {"description": "sofa"}}
]
}}
]
}
}
}
You can nest a bool query inside the filter context, and should is only valid from within a bool clause.
It's an old reference sir, but it still checks out:
https://www.elastic.co/guide/en/elasticsearch/guide/current/combining-filters.html

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

ElasticSearch How to AND a nested query

I am trying to figure out how to AND my Elastic Search query. I've tried a few different variations but I am always hitting a parser error.
What I have is a structure like this:
{
"title": "my title",
"details": [
{ "name": "one", "value": 100 },
{ "name": "two", "value": 21 }
]
}
I have defined details as a nested type in my mappings. What I'm trying to achieve is a query where it matches a part of the title and it matches various details by the detail's name and value.
I have the following query which gets me nearly there but I haven't been able to figure out how to AND the details. As an example I'd like to find anything that has:
detail of one with value less than or equal to 100
AND detail of two with value less than or equal to 25
The following query only allows me to search by one detail name/value:
"query" : {
"bool": {
"must": [
{ "match": {"title": {"query": titleQuery, "operator": "and" } } },
{
"nested": {
"path": "details",
"query": {
"bool": {
"must": [
{ "match": {"details.name" : "one"} },
{ "range": {"details.value" : { "lte": 100 } } }
]
}
}
} // nested
}
] // must
}
}
As a second question, would it be better to query the title and then move the nested part of the query into a filter?
You were so close! Just add another "nested" clause in your outer "must":
POST /test_index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"title": {
"query": "title",
"operator": "and"
}
}
},
{
"nested": {
"path": "details",
"query": {
"bool": {
"must": [
{"match": {"details.name": "one" } },
{ "range": { "details.value": { "lte": 100 } } }
]
}
}
}
},
{
"nested": {
"path": "details",
"query": {
"bool": {
"must": [
{"match": {"details.name": "two" } },
{ "range": { "details.value": { "lte": 25 } } }
]
}
}
}
}
]
}
}
}
Here is some code I used to test it:
http://sense.qbox.io/gist/1fc30d49a810d22e85fa68d781114c2865a7c92e
EDIT: Oh, the answer to your second question is "yes", though if you're using 2.0 things have changed a little.

Elastic search DSL Syntax equivalence for SQL statement

I'm trying to replicate the below query logic in an elastic search query but something's not right.
Basically the query below returns one doc. I'd like either the first condition to be applied: "name": "iphone" OR the more complex second one which is: (username = 'gogadget' AND status_type = '1' AND created_time between 4532564 AND 64323238). Note that the nested bool must inside the should would take care of the more complex condition. I should still see 1 doc if I change the outside match of "name": "iphone" to be changed to "name": "wrong value". But I get nothing when I do that. I'm not sure where this is wrong.
The SQL Query is here below.
SELECT * from data_points
WHERE name = 'iphone'
OR
(username = 'gogadget' AND status_type = '1' AND created_time between 4532564 AND 64323238)
{
"size": 30,
"query": {
"bool": {
"must": [
{
"bool": {
"minimum_should_match": "1",
"should": [
{
"bool": {
"must": [
{
"match": {
"username": "gogadget"
}
},
{
"terms": {
"status_type": [
"3",
"4"
]
}
},
{
"range": {
"created_time": {
"gte": 20140712,
"lte": 1405134711
}
}
}
]
}
}
],
"must": [],
"must_not": []
}
},
{
"match": {
"name": "iphone"
}
}
]
}
}
}
should query will match the query and return.
You don't need use must to aggregate your OR query.
The query should like:
{
"query": {
"bool": {
"should": [{
"bool": {
"must": [{
"match": {
"username": "gogadget"
}
}, {
"terms": {
"status_type": [
"3",
"4"
]
}
}, {
"range": {
"created_time": {
"gte": 20140712,
"lte": 1405134711
}
}
}]
}
}, {
"match": {
"name": "iphone"
}
}]
}
}
}

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