Elasticsearch - how to know if a particular match condition was hit - elasticsearch

Hello elastic experts!
I am new to elasticsearch. I am trying to build a search query with multiple or matching. I am boosting the query for different matching conditions. But here I need a bit more information. I need to know which conditions contributed to the search result. Is there any way to know which match conditions were hit by the query string?
{
"query": {
"bool": {
"should": [
{
"term": {
"title.keyword": {
"value": "Ski trip",
"boost": 1
}
}
},
{
"match_phrase_prefix": {
"title": {
"query": "Ski trip",
"boost": 0.8
}
}
},
{
"match": {
"title": {
"query": "Ski trip",
"operator": "and",
"boost": 0.6
}
}
},
{
"match": {
"description": {
"query": "Ski trip",
"boost": 0.3
}
}
}
]
}
}
}

Related

Why does Elasticsearch score these documents the way it does?

I have a query where I'm trying pull documents out of my index and sort them by a date. Additionally, if the document's ID matches a provided one then I boost that result.
When I run my query I'm noticing that some of the documents with a more recent sort date are not at the top of the results because Elasticsearch is giving them a different score than other documents. As a result my result order is incorrect. I don't see anything in my query that could be affecting the score. Anyone have any idea what's happening?
Here's the query I'm using:
{
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"language.keyword": {
"query": "english",
"operator": "OR",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"functions": [
{
"filter": {
"match": {
"id": {
"query": "ID1",
"operator": "OR",
"boost": 1
}
}
},
"weight": 10
}
],
"score_mode": "multiply",
"boost_mode": "multiply",
"boost": 1
}
},
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"sortDate": {
"order": "desc"
}
}
]
}

Elasticsearch query + filter

This is my original query dsl, and total of hits was 8,981.
GET /{index}/{document}/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "blue shoes",
"boost": 2
}
}
},
{
"match": {
"description": {
"query": "blue shoes",
"operator": "and",
"boost": 1
}
}
}
]
}
}
}
I want to add filter to this query.
GET /{index}/{document}/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": {
"query": "blue shoes",
"boost": 2
}
}
},
{
"match": {
"description": {
"query": "blue shoes",
"operator": "and",
"boost": 1
}
}
}
],
"filter": {
"terms": {
"store.id": [ "store_a.com", "store_b.com" ]
}
}
}
}
}
Now its total of hits is 15,989(increased).
And I sort the result by score in asc(I don't know why it's asc not desc), there are documents which is scored 0.
I think there is no more filtering by query because it is already filtered.
Can I remove 0 scored documents from the result?
To add a filter, use a must clause in your bool query to add a mandatory value. Try :
GET /{index}/{document}/_search
{
"query": {
"bool": {
"must": [
"terms": {
"store.id": [ "store_a.com", "store_b.com" ]
}
],
"should": [
{
"match": {
"title": {
"query": "blue shoes",
"boost": 2
}
}
},
{
"match": {
"description": {
"query": "blue shoes",
"operator": "and",
"boost": 1
}
}
}
]
}
}
}

How can we use exists query in tandem with the search query?

I have a scenario in Elasticsearch where my indexed docs are like this :-
{"id":1,"name":"xyz", "address": "xyz123"}
{"id":1,"name":"xyz", "address": "xyz123"}
{"id":1,"name":"xyz", "address": "xyz123", "note": "imp"}
Here the requirement stress that we have to do a term match query and then provide relevance score to them which is a straight forward thing but the additional aspect here is if any doc found in search result has note field then it should be given higher relevance. How can we achieve it with DSL query? Using exists we can check which docs contain notes but how to integrate with match query in ES query. Have tried lot of ways but none worked.
With ES 5, you could boost your exists query to give a higher score to documents with a note field. For example,
{
"query": {
"bool": {
"must": {
"match": {
"name": {
"query": "your term"
}
}
},
"should": {
"exists": {
"field": "note",
"boost": 4
}
}
}
}
}
With ES 2, you could try a boosted filtered subset
{
"query": {
"function_score": {
"query": {
"match": { "name": "your term" }
},
"functions": [
{
"filter": { "exists" : { "field" : "note" }},
"weight": 4
}
],
"score_mode": "sum"
}
}
}
I believe that you are looking for boosting query feature
https://www.elastic.co/guide/en/elasticsearch/reference/5.1/query-dsl-boosting-query.html
{
"query": {
"boosting": {
"positive": {
<put yours original query here>
},
"negative": {
"filtered": {
"filter": {
"exists": {
"field": "note"
}
}
}
},
"negative_boost": 4
}
}
}

terms query does not support minimum_match in Elasticsearch 2.3.3

I want to search documents which match at least two key words using terms query like this:
{
"query": {
"terms": {
"title": ["java","编程","思想"],
"minimum_match": 2
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
It returns "terms query does not support minimum_match".What's wrong with my query?
The correct name was minimum_should_match and that setting has been deprecated in ES 2.0.
What you can do instead is to use a bool/should query with three term queries and the minimum_should_match setting for bool/should queries:
{
"query": {
"bool": {
"minimum_should_match": 2,
"should": [
{
"term": {
"title": "java"
}
},
{
"term": {
"title": "编程"
}
},
{
"term": {
"title": "思想"
}
}
]
}
},
"highlight": {
"fields": {
"title": {}
}
}
}

Elasticsearch Parse Exception for boolean queries

I'm trying to create queries similar to kibana queries in elasticsearch lucene queries. What I'm basically trying to do is matching some phrases. For example; my kibana query looks like this:(+"anna smith") AND ( (+"university"), (+"chairman"), (+"women rights")) It searches "anna smith" as must and one of the other phrases as should(there should be at least one of them exist in the text). I wrote a query to do this but it gives "elasticsearch parse exception:expected field name but got start_object". How can I solve this. Here is my query;
{
"query": {
"bool": {
"must": {
"match": {
"text": {
"query": "anna smith",
"operator": "and"
}
}
}
},
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"text": {
"query": "university",
"boost": 2
}
}
},
{
"match": {
"text": {
"query": "chairman",
"boost": 2
}
}
}
]
}
}]
}}}}
Your second query at the bottom cannot be there, it needs to be inside the first bool/must like this
{
"query": {
"bool": {
"must": [
{
"match": {
"text": {
"query": "anna smith",
"operator": "and"
}
}
},
{
"bool": {
"should": [
{
"match": {
"text": {
"query": "university",
"boost": 2
}
}
},
{
"match": {
"text": {
"query": "chairman",
"boost": 2
}
}
}
]
}
}
]
}
}
}

Resources