I have this fairly simple es query and filter, using ES 2.3.5:
{
"query": {
"multi_match": {
"query": "image",
"fields": [
"ToRecipients"
"From",
"Subject"
]
}
},
"filter": {
"bool": {
"must": [
{
"match": {
"ToRecipients": "johndoe"
}
}
]
}
},
"sort": [
{
"DateTimeSent": {
"order": "desc"
}
}
]
}
For some reason it is not filtering by the ToRecipients field. The results coming back have all kinds of values for the field not just johndoe.
Where have I gone wrong?
Try this query instead:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "image",
"fields": [
"ToRecipients",
"From",
"Subject"
]
}
}
],
"filter": {
"bool": {
"must": [
{
"match": {
"ToRecipients": "johndoe"
}
}
]
}
}
}
},
"sort": [
{
"DateTimeSent": {
"order": "desc"
}
}
]
}
Related
I would like to have an intersection of 2 queries
I got 3 documents in the index:
"_id": "68c220aa-ea51-4f84-b880-29af3302cae9",
"_id": "b6c1c3c5-e959-480f-a145-f5598fafea66",
"_id": "2d30de72-0a2b-465c-8770-970ad9760d47",
Query1:
{
"from": 0,
"query": {
"nested": {
"path": "attributes",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"match_phrase": {
"attributes.asReference": {
"query": "8670ff39-6a0d-4ae8-e217-08d88efd4771"
}
}
},
{
"match_phrase": {
"attributes.attributeId": {
"query": "f51ca670-4223-4ea2-8007-d111dd38a14f"
}
}
}
]
}
}
]
}
}
}
},
"size": 10,
"sort": [
{
"modified": {
"order": "asc"
}
},
{
"created": {
"order": "asc"
}
}
]
}
returns all 3 documents as it should
"_id": "68c220aa-ea51-4f84-b880-29af3302cae9",
"_id": "b6c1c3c5-e959-480f-a145-f5598fafea66",
"_id": "2d30de72-0a2b-465c-8770-970ad9760d47",
Then I do query2:
{
"from": 0,
"query": {
"nested": {
"path": "attributes",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"match_phrase": {
"attributes.asShortString": {
"query": "RA-005"
}
}
},
{
"match_phrase": {
"attributes.attributeId": {
"query": "7ff3dbc1-3586-4475-9162-5430bb06c6d0"
}
}
}
]
}
}
]
}
}
}
},
"size": 10,
"sort": [
{
"modified": {
"order": "asc"
}
},
{
"created": {
"order": "asc"
}
}
]
}
returns 1 document:
"_id": "b6c1c3c5-e959-480f-a145-f5598fafea66"
But when I combine the queries to:
{
"from": 0,
"query": {
"nested": {
"path": "attributes",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"match_phrase": {
"attributes.asReference": {
"query": "8670ff39-6a0d-4ae8-e217-08d88efd4771"
}
}
},
{
"match_phrase": {
"attributes.attributeId": {
"query": "f51ca670-4223-4ea2-8007-d111dd38a14f"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"match_phrase": {
"attributes.asShortString": {
"query": "RA-005"
}
}
},
{
"match_phrase": {
"attributes.attributeId": {
"query": "7ff3dbc1-3586-4475-9162-5430bb06c6d0"
}
}
}
]
}
}
]
}
}
}
},
"size": 10,
"sort": [
{
"modified": {
"order": "asc"
}
},
{
"created": {
"order": "asc"
}
}
]
}
Here I do not get any documents
So the subqueries are working but combined it does not work (it produces 0 results)
What am I missing here?
Due to the way nested documents and queries work, you need to have two separate nested queries in your bool/must query, because each will/might match a different nested document of the same parent document:
{
"from": 0,
"query": {
"bool": {
"must": [
{
"nested": {
"path": "attributes",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"match_phrase": {
"attributes.asReference": {
"query": "8670ff39-6a0d-4ae8-e217-08d88efd4771"
}
}
},
{
"match_phrase": {
"attributes.attributeId": {
"query": "f51ca670-4223-4ea2-8007-d111dd38a14f"
}
}
}
]
}
}
]
}
}
}
},
{
"nested": {
"path": "attributes",
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"match_phrase": {
"attributes.asShortString": {
"query": "RA-005"
}
}
},
{
"match_phrase": {
"attributes.attributeId": {
"query": "7ff3dbc1-3586-4475-9162-5430bb06c6d0"
}
}
}
]
}
}
]
}
}
}
}
]
}
},
"size": 10,
"sort": [
{
"modified": {
"order": "asc"
}
},
{
"created": {
"order": "asc"
}
}
]
}
I am trying to perform a search by matching the search query to either the tag or the name of the doc, I also have a filter on the top, so I do have to use must.
Here is what I have been trying,
{
"query": {
"bool": {
"filter": {
"term": {
"type.primary": "audio"
}
},
"must": [
{
"nested": {
"path": "tags",
"score_mode": "sum",
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"tags.tag": "big"
}
}
]
}
},
"field_value_factor": {
"field": "tags.weight"
},
"boost_mode": "multiply",
"boost": 10
}
}
}
},
{
"bool": {
"must": [
{
"multi_match": {
"query": "big",
"fields": [
"name"
],
"type": "phrase_prefix"
}
}
]
}
}
]
}
}
}
This just results in empty.
If I use should instead of must the query works fine, but it gives me all results with the filter of type.primary: audio.
I am pretty sure there is some other way to search for the name field. Thanks.
You're almost there! In your must, you declare that both tags and name has to hit. Try the following:
GET /_search
{
"query": {
"bool": {
"filter": {
"term": {
"type.primary": "audio"
}
},
"must": [
{
"bool": {
"should": [
{
"nested": {
"path": "tags",
"score_mode": "sum",
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"tags.tag": "big"
}
}
]
}
},
"field_value_factor": {
"field": "tags.weight"
},
"boost_mode": "multiply",
"boost": 10
}
}
}
},
{
"multi_match": {
"query": "big",
"fields": [
"name"
],
"type": "phrase_prefix"
}
}
]
}
}
]
}
}
}
I'm very new to Elasticsearch. I'm using it to filtering and also boosting some fields at query time. This is the code part for boosting and filtering:
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"multi_match": {
"type": "best_fields",
"query": "exampleKeyword",
"fields": [
"exampleField1^0",
"exampleField2^50",
"exampleField3^10",
"exampleField4^10",
"exampleField5^5"
],
"boost": 50
}
}]
}
}
],
"filter": [
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"bla": {
"value": ""
}
}
}
]
}
}, {
"term": {
"active": {
"value": "true"
}
}
},
{
"range": {
"closingDate": {
"gte": "201710310000",
"lte": "999912312359"
}
}
},
Now I want to boost some specific documents. I'll give an array of integers for example Field6 and if my search results contain the elements of the array, these documents should get boosted with, I dont know, 100 to my scale.
How can I do this? Finally I dont want to expand the result set. Just want to boost more the desired ids if results contain these ids.
Using function_score you can do something around these lines:
{
"query": {
"bool": {
"must": [
{
"function_score": {
"query": {
"bool": {
"should": [
{
"multi_match": {
"type": "best_fields",
"query": "bla",
"fields": [
"exampleField1^0",
"exampleField2^50",
"exampleField3^10",
"exampleField4^10",
"exampleField5^5"
],
"boost": 50
}
}
]
}
},
"functions": [
{
"filter": {
"ids": {
"values": [
1,
5
]
}
},
"weight": 10
}
],
"score_mode": "max",
"boost_mode": "multiply"
}
}
],
"filter": [
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"bla": {
"value": ""
}
}
}
]
}
},
{
"term": {
"active": {
"value": "true"
}
}
},
{
"range": {
"closingDate": {
"gte": "201710310000",
"lte": "999912312359"
}
}
}
]
}
}
]
}
}
}
I'm trying to do a elasticsearch query that does geolocation filter and does some matching on nested documents, but I'm getting this error whenever I add in the nested query.
"[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]"
{
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "10km",
"geolocation": [
-73.980090948125,
40.747844918436
]
}
},
"must": {
"multi_match": {
"query": "New York",
"fields": [
"name^2",
"city",
"state",
"zip"
],
"type": "best_fields"
}
}
},
"nested": {
"path": "amenities",
"query": {
"bool": {
"must": [
{
"match": {
"amenities.name": "Pool"
}
}
]
}
}
}
},
"aggs": {
"reviews": {
"nested": {
"path": "reviews"
},
"aggs": {
"avg_rating": {
"avg": {
"field": "reviews.rating"
}
}
}
}
}
}
You just has misplaced the nested query, try like this:
{
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"query": {
"bool": {
"filter": {
"geo_distance": {
"distance": "10km",
"geolocation": [
-73.980090948125,
40.747844918436
]
}
},
"must": [
{
"multi_match": {
"query": "New York",
"fields": [
"name^2",
"city",
"state",
"zip"
],
"type": "best_fields"
}
},
{
"nested": {
"path": "amenities",
"query": {
"match": {
"amenities.name": "Pool"
}
}
}
}
]
}
},
"aggs": {
"reviews": {
"nested": {
"path": "reviews"
},
"aggs": {
"avg_rating": {
"avg": {
"field": "reviews.rating"
}
}
}
}
}
}
In the following code I always get "Alexander McQueen" products coming first, no matter what I set the seed to.
How can I change my search query to properly shuffle results?
{
"query": {
"function_score": {
"random_score": {
"seed": 99287
},
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"query_string": {
"query": "(adidas originals)",
"default_operator": "AND",
"fields": [
"name^4",
"description"
]
}
},
{
"terms": {
"category": [
"Fashion",
"Sports",
"Other",
""
]
}
},
{
"term": {
"currency": {
"term": "USD"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"query_string": {
"query": "(alexander mcqueen)",
"default_operator": "AND",
"fields": [
"name^4",
"description"
]
}
},
{
"terms": {
"category": [
"Fashion"
]
}
},
{
"term": {
"currency": {
"term": "USD"
}
}
}
]
}
}
]
}
}
}
},
"size": 40,
"from": 0
}
That's because the random score is being multiplied by the _score from the original query. If you want the results to be purely based on the random score, then set the boost_mode to replace (instead of the default multiply).
See the function_score documentation.