Elasticsearch - OR in term conditions - elasticsearch

I need little help with transfering mysql query to ES. The query looks like this
SELECT * FROM `xyz` WHERE visibility IN (1,2) AND (active=0 OR (active=1 AND finished=1)
It's easy, to make only AND conditions, but how to mix AND with OR in term?
"query" : {
"bool" : {
"must" : [{
"terms" : { "visibility" : ["1", "2"] }
}, {
"term" : { "active" : "1" }
}, {
"term" : { "active" : "0", "finished" : "1" } // OR
},]
}
}

Try like this by nesting a bool/should and bool/filter query inside the main bool/filter query:
{
"query": {
"bool": {
"filter": [
{
"terms": {
"visibility": [
"1",
"2"
]
}
},
{
"bool": {
"should": [
{
"term": {
"active": "0"
}
},
{
"bool": {
"filter": [
{
"term": {
"active": "1"
}
},
{
"term": {
"finished": "1"
}
}
]
}
}
]
}
}
]
}
}
}

Related

Elastic search source filtering query for nested JSON document

I have the below JSON object as _source in Elastic search. I need to filter the source object based on conditions. For example, I need only JSON with applied_as == "COMMISSION"
"_source": {
"factor" : [
{
"some_amount_usd" : [
{
"applied_as" : "TCKT_CNT",
"version" : "8",
"factor_value" : "1.12",
"start_date" : "2022-01-01"
},
{
"applied_as" : "TCKT_CNT",
"version" : "8",
"factor_value" : "1.12",
"start_date" : "2022-02-01"
},
{
"applied_as" : "COMMISSION",
"version" : "8",
"factor_value" : "1.12",
"start_date" : "2022-02-01"
},
]
}
]
}
I am using this documentation.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-fields.html#source-filtering
I am currently using this query with no luck. What am I missing?
GET form_some_index/_search
{
"query": {
"match": {
"factor.some_amount_usd.applied_as": "COMMISSION"
}
}
}
You can start using Nested Query.
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"path": "factor",
"query": {
"nested": {
"path": "factor.some_amount_usd",
"query": {
"bool": {
"must_not": [
{
"term": {
"factor.some_amount_usd.applied_as.keyword": {
"value": "COMMISSION"
}
}
}
]
}
}
}
}
}
}
]
}
}
}

Elastic search combine must and must_not

I have a document that holds data for a product the mapping is as follow:
"mappings" : {
"properties" : {
"view_score" : {
"positive_score_impact" : true,
"type" : "rank_feature"
},
"recipients" : {
"dynamic" : false,
"type" : "nested",
"enabled" : true,
"properties" : {
"type" : {
"similarity" : "boolean",
"type" : "keyword"
},
"title" : {
"type" : "text",
"fields" : {
"key" : {
"type" : "keyword"
}
}
}
}
}
}
}
And I have 2 documents with the following data:
{
"view_score": 10,
"recipients": [{"type":"gender", "title":"male"}, {"type":"gender", "title":"female"}]
}
{
"view_score": 10,
"recipients": [{"type":"gender", "title":"female"}]
}
When a user searches for a product she can say "I prefer products for females" so The products which specifies gender as just female should come before products that specifies gender as male and female both.
I have the following query which gives more score to products with just female gender:
GET _search
{
"sort": [
"_score"
],
"query": {
"script_score": {
"query": {
"bool": {
"should": [
{
"nested": {
"path": "recipients",
"ignore_unmapped": true,
"query": {
"bool": {
"boost": 10,
"must": [
{
"term": {
"recipients.type": "gender"
}
},
{
"match": {
"recipients.title": "female"
}
}
],
"must_not": {
"bool": {
"filter": [
{
"term": {
"recipients.type": "gender"
}
},
{
"match": {
"recipients.title": "male"
}
}
]
}
}
}
}
}
}
]
}
},
"script": {
"source": "return _score;"
}
}
}
}
But if I add another query to should query it won't behave the same and gives the same score to products with one or two genders in their specifications.
here is my final query which wont work as expected:
GET _search
{
"sort": [
"_score"
],
"query": {
"script_score": {
"query": {
"bool": {
"should": [
{
"rank_feature": {
"field": "view_score",
"linear": {}
}
},
{
"nested": {
"path": "recipients",
"ignore_unmapped": true,
"query": {
"bool": {
"boost": 10,
"must": [
{
"term": {
"recipients.type": "gender"
}
},
{
"match": {
"recipients.title": "female"
}
}
],
"must_not": {
"bool": {
"filter": [
{
"term": {
"recipients.type": "gender"
}
},
{
"match": {
"recipients.title": "male"
}
}
]
}
}
}
}
}
}
]
}
},
"script": {
"source": "return _score;"
}
}
}
}
So my problem is how to combine these should clause together to give more weight to the products that specify only one gender.

How to pass array to ElasticSearch search template using mustache?

This is a part of my search query template:
"query": {
"bool": {
"must": [
{
"terms": {
"platform_id": [
"{{#platform_ids}}",
"{{.}}",
"{{/platform_ids}}"
]
}
}
],
This solution was taken from the elasticsearch official website.
I have this query:
GET _render/template
{
"id": "fddf",
"params": {
"query_string": "tinders",
"platform_ids": [1, 2]
}
}
And this results with this:
"terms" : {
"platform_id" : [
"",
"1",
"",
"2",
""
]
}
But I need this:
"terms" : {
"platform_id" : [
1, 2
]
}
Couldn't find a solution for this.
You need to modify your template as shown below
GET _render/template
{
"source": "{\"query\":{\"bool\":{\"must\":[{\"terms\":{\"platform_id\":[{{#platform_id}}{{value}}{{#comma}},{{/comma}}{{/platform_id}}]}}]}}}",
"params": {
"platform_id": [
{
"value": 1,
"comma": true
},
{
"value": 2
}
]
}
}
Result would be
{
"template_output": {
"query": {
"bool": {
"must": [
{
"terms": {
"platform_id": [
1,
2
]
}
}
]
}
}
}
}
Refer to this SO answer to get a detailed explanation
Request:
GET _render/template
{
"source": "{ \"query\": { \"terms\": {{#toJson}}bids{{/toJson}} }}",
"params": {
"bids":[1,2]
}
}
Response:
{
"template_output" : {
"query" : {
"terms" : [
1,
2
]
}
}
}
Try below:
"query": {
"bool": {
"must": [
{
"terms": {
"platform_id": {{#toJson}}platform_id{{/toJson}}
}
}
],

Elastic Search 1.7.3 Nested filter: matching terms in an array of objects

I am trying to query for the following document in my elasticsearch:
"amenity": [
"Free Wifi",
"Free Breakfast",
"Veg Only",
"Swimming Pool",
"Newspaper",
"Bar",
"Credit Card",
"Pickup & Drop",
"Gym",
"Elevator",
"Valet Parking"
],
"dodont": [
{
"do_or_dont": "Do",
"what": "Vegetarians"
},
{
"do_or_dont": "Do",
"what": "Family"
},
{
"do_or_dont": "Dont",
"what": "Loud Music"
},
{
"do_or_dont": "Dont",
"what": "Booze"
}
]
and here is the query I have written:
"filter": {
"and": {
"filters": [
{
"nested" : {
"path" : "dodont",
"filter" : {
"bool" : {
"must": [{"and" : [
{
"term" : {"dodont.do_or_dont" : "Do"}
},
{
"term" : {"dodont.what" : "Vegetarians"}
}
]},
{"and" : [
{
"term" : {"dodont.do_or_dont" : "Do"}
},
{
"term" : {"dodont.what" : "Family"}
}
]}]
}
}
}
}
]
}
}
Now this query returns empty result, but when I change the "must" to "should" in the bool in above code, it returns the above document as the result (there is only 1 document matching this filter the one shown above), but ideally, the "must" condition should return the above document, I want to pass multiple objects for Do's and donts and I only want the results which match all of them, but I am not able to do so. How should I go about it?
You need to split out the two conditions on your nested document, since each element of the dodont nested array is conceptually a separate document:
{
"filter": {
"and": {
"filters": [
{
"nested": {
"path": "dodont",
"filter": {
"and": [
{
"term": {
"dodont.do_or_dont": "Do"
}
},
{
"term": {
"dodont.what": "Vegetarians"
}
}
]
}
}
},
{
"nested": {
"path": "dodont",
"filter": {
"and": [
{
"term": {
"dodont.do_or_dont": "Do"
}
},
{
"term": {
"dodont.what": "Family"
}
}
]
}
}
}
]
}
}
}

Elasticsearch match list against field

I have a list, array or whichever language you are familiar. E.g. names : ["John","Bas","Peter"] and I want to query the name field if it matches one of those names.
One way is with OR Filter. e.g.
{
"filtered" : {
"query" : {
"match_all": {}
},
"filter" : {
"or" : [
{
"term" : { "name" : "John" }
},
{
"term" : { "name" : "Bas" }
},
{
"term" : { "name" : "Peter" }
}
]
}
}
}
Any fancier way? Better if it's a query than a filter.
{
"query": {
"filtered" : {
"filter" : {
"terms": {
"name": ["John","Bas","Peter"]
}
}
}
}
}
Which Elasticsearch rewrites as if you hat used this one
{
"query": {
"filtered" : {
"filter" : {
"bool": {
"should": [
{
"term": {
"name": "John"
}
},
{
"term": {
"name": "Bas"
}
},
{
"term": {
"name": "Peter"
}
}
]
}
}
}
}
}
When using a boolean filter, most of the time, it is better to use the bool filter than and or or. The reason is explained on the Elasticsearch blog: http://www.elasticsearch.org/blog/all-about-elasticsearch-filter-bitsets/
As I tried the filtered query I got no [query] registered for [filtered], based on answer here it seems the filtered query has been deprecated and removed in ES 5.0. So I provide using:
{
"query": {
"bool": {
"filter": {
"terms": {
"name": ["John","Bas","Peter"]
}
}
}
}
}
example query = filter by keyword and a list of values
{
"query": {
"bool": {
"must": [
{
"term": {
"fguid": "9bbfe844-44ad-4626-a6a5-ea4bad3a7bfb.pdf"
}
}
],
"filter": {
"terms": {
"page": [
"1",
"2",
"3"
]
}
}
}
}
}

Resources