I have this kind of sort:
"sort": [
{
"_script": {
"script": "return doc.score*10 + doc['field2'].value",
"type": "number",
"order": "asc"
}
}
]
partial fields:
"filter": {
"partial_fields": {
"fields": {
"exclude": [
"field5*"
]
}
}
}
Problem is that sort does not work if partial_fields is set.. is there a reason for this ? or how do I have to remove partial_fields in order to get sort working ?
here's the whole query:
{
"size": 10,
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"text": {
"name_en": {
"query": "testing",
"operator": "or",
"boost": 20
}
}
}
]
}
},
"filter": {
"and": [
{
"term": {
"_type": "test"
}
}
]
}
},
"filter": {
"partial_fields": {
"fields": {
"exclude": [
"field2*"
]
}
}
}
},
"sort": [
{
"_script": {
"script": "return doc.score*1000 + doc['field2'].value",
"type": "number",
"order": "asc"
}
}
]
}
Thanks.
According to the documentation for partial fields, I do not see the usage as being nested under a filter node in the JSON request. I think this could be your issue, try moving the partial_fields section up to the same level as sort like the following:
{
"size": 10,
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"text": {
"name_en": {
"query": "testing",
"operator": "or",
"boost": 20
}
}
}
]
}
},
"filter": {
"and": [
{
"term": {
"_type": "test"
}
}
]
}
}
},
"partial_fields": {
"fields": {
"exclude": [
"field2*"
]
}
},
"sort": [
{
"_script": {
"script": "return doc.score*1000 + doc['field2'].value",
"type": "number",
"order": "asc"
}
}
]
}
Related
I implemented function_score successfully for queries running against one index, but have trouble to apply function_score to a query spanning multiple indices with different fields in ElasticSearch 6.2.4.
This query:
POST /web_document,web_part/_search
{
"from": 0,
"size": 100,
"query": {
"function_score": {
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"type": "best_fields",
"query": "sampling probe",
"fields": [
"titleD.autocomplete^5",
"titleE.autocomplete^5"
]
}
}
],
"filter": [
{
"term": {
"_index": {
"value": "web_document"
}
}
}
]
}
},
{
"bool": {
"must": [
{
"multi_match": {
"type": "best_fields",
"query": "sampling probe",
"fields": [
"textD.autocomplete^5",
"textE.autocomplete^5"
]
}
}
],
"filter": [
{
"term": {
"_index": {
"value": "web_part"
}
}
}
]
}
}
]
}
},
"functions": [
{
"filter": {
"bool": {
"must_not": [
{ "exists": { "field": "revDestDate" } },
{ "exists": { "field": "mutationDate" } }
]
}
},
"script_score": {
"script": "100"
}
},
{
"filter": {
"term": {
"_index": "web_part"
}
},
"gauss": {
"mutationDate": {
"origin": "now",
"scale": "90d",
"decay": 0.5
}
},
"weight": 20
},
{
"filter": {
"term": {
"_index": "web_document"
}
},
"gauss": {
"revDestDate": {
"origin": "now",
"scale": "90d",
"decay": 0.5
}
},
"weight": 20
}
],
"score_mode" : "first",
"boost_mode": "sum"
}
}
}
Returns the following error:
{
"error": {
…
"failed_shards": [
{
"index": "web_document",
…
"reason": {
"type": "parsing_exception",
"reason": "unknown field [mutationDate]",
…
}
},
{
"index": "web_part",
…
"reason": {
"type": "parsing_exception",
"reason": "unknown field [revDestDate]",
…
}
}
]
},
"status": 400
}
I also tried to incorporate the function_score in the induvidual query like this,
which returns the same error:
POST /web_document,web_part/_search
{
"from": 0,
"size": 100,
"query": {
"bool": {
"should": [
{
"function_score": {
"query": {
"bool": {
"must": [
{
"multi_match": {
"type": "best_fields",
"query": "sampling probe",
"fields": [
"titleD.autocomplete^5",
"titleE.autocomplete^5"
]
}
}
],
"filter": [
{
"term": {
"_index": {
"value": "web_document"
}
}
}
]
}
},
"functions": [
{
"gauss": {
"revDestDate": {
"origin": "now",
"scale": "90d",
"decay": 0.5
}
}
}
]
}
},
{
"function_score": {
"query": {
"bool": {
"must": [
{
"multi_match": {
"type": "best_fields",
"query": "sampling probe",
"fields": [
"textD.autocomplete^5",
"textE.autocomplete^5"
]
}
}
],
"filter": [
{
"term": {
"_index": {
"value": "web_part"
}
}
}
]
}
},
"functions": [
{
"gauss": {
"mutationDate": {
"origin": "now",
"scale": "90d",
"decay": 0.5
}
}
}
]
}
}
]
}
}
}
According to the comment from Darshan Pratil to this answer to the same problem this has worked in past versions.
How can this be done in elastic search 6.2.4?
so here is my problem, I have query builder that builds a query according to the params that are sent to an API, here is one example of queries that it builds
{
"from": 0,
"size": 50,
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "nrc",
"fields": [
"name",
"sector.group.name",
"description",
"professionDescription"
]
}
},
{
"term": {
"alternate": "true"
}
},
{
"term": {
"flagInitial": "true"
}
},
{
"term": {
"flagDistance": "true"
}
}
],
"must": [],
"minimum_should_match": 2
}
},
"filter": {
"geo_distance": {
"distance": "80km",
"institute.location": {
"lat": "48.866667",
"lon": "2.333333"
}
}
}
}
},
"track_scores": true,
"sort": {
"institute.premium": {
"order": "desc"
},
"_geo_distance": {
"location": {
"lat": "48.866667",
"lon": "2.333333"
}
}
}
}
As you can see we have a multi-match, and different flags, and the whole query is filtered using geo_distance around given coords. In this case, the issue is that we don't want this filter to apply to the term "flagDistance", because if flagDistance=true, we want all the institutes that have flagDistance=true regardless where they are, but we still want this filter to apply to the other flags/multi_match of the query.
Any ideas how to do that ?
I was hoping I could add another query after the first (filtered one), but it returns an error
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "nrc",
"fields": [
"name",
"sector.group.name",
"description",
"professionDescription"
]
}
},
{
"term": {
"alternate": "true"
}
},
{
"term": {
"flagInitial": "true"
}
}
],
"must": [],
"minimum_should_match": 2
}
},
"filter": {
"geo_distance": {
"distance": "80km",
"institute.location": {
"lat": "48.866667",
"lon": "2.333333"
}
}
}
},
"bool": {
"should": [
{
"term": {
"flagDistance": "true"
}
}
]
}
}
so this is how I solved my problem, that should clause in my filter allows me to filter either if it's a flagDistance = true document, or if it's 80km's from the given coords
{
"from": 0,
"size": 50,
"query": {
"filtered": {
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "muc",
"fields": [
"name",
"sector.group.name",
"description",
"professionDescription"
]
}
},
{
"term": {
"alternate": "true"
}
},
{
"term": {
"flagDistance": "true"
}
}
],
"must": [],
"minimum_should_match": 2
}
},
"filter": {
"bool": {
"should": {
"geo_distance": {
"distance": "80km",
"institute.location": {
"lat": "48.866667",
"lon": "2.333333"
}
},
"term": {
"flagDistance": "true"
}
}
}
}
}
},
"track_scores": true,
"sort": {
"institute.premium": {
"order": "desc"
},
"_geo_distance": {
"location": {
"lat": "48.866667",
"lon": "2.333333"
}
}
}
}
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"
}
}
}
}
}
}
This is my search:
{
"query": {
"filtered": {
"filter": {
"term": { "cityId": "10777"}
},
"query" : {
"query_string": {
"query": "pizza",
"fields": ["name", "main", "category.name"]
}
}
}
},
"sort": [
{ "premium": { "order": "desc" } }
]
}
This works perfectly.
He brings me several categories, and I would like to group by them.
example:
Group by category "pizzerias"
All you have to do is to add a terms aggregation to the mix and you're done.
Supposing your category field is the category.name one, you can do it like this.
{
"query": {
"filtered": {
"filter": {
"term": {
"cityId": "10777"
}
},
"query": {
"query_string": {
"query": "pizza",
"fields": [
"name",
"main",
"category.name"
]
}
}
}
},
"sort": [
{
"premium": {
"order": "desc"
}
}
],
"aggs": {
"categories": {
"terms": {
"field": "category.name"
}
}
}
}
I want to check for documents that have media_url == '' || media_url == null. I have a query:
{
"engagements": [
"blah"
],
"query": {
"from": 0,
"size": 2,
"sort": [
{
"bookmarked": {
"order": "desc"
}
},
{
"created_at": {
"order": "desc"
}
}
],
"facets": {},
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"car_id": "78778"
}
},
{
"range": {
"created_at": {
"gte": "2015-04-12T04:00:00.000Z",
"lte": "2015-05-13T03:59:59.999Z"
}
}
},
{
"term": {
"media_url": ""
}
}
],
"should": [
{
"term": {
"bookmarked": false
}
}
]
}
}
}
},
"aggregations": {
"word_frequencies": {
"terms": {
"field": "text",
"size": 150
}
}
},
"highlight": {
"fields": {
"text": {
"fragment_size": 1500
}
}
}
},
"api": "_search"
}
However, if I do what I do above, then records that are set to null wouldn't be returned. What should I do to return records with either '' or null as their media_url value?
Perhaps you can try using the "or" filter.
http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-or-filter.html
{
"or": [
{
"term": {
"media_url": ""
}
},
{
"term": {
"media_url": null
}
}
]
}
Edit: Here's the full query (untested since I don't have an example document/index template)
{
"engagements": [
"blah"
],
"query": {
"from": 0,
"size": 2,
"sort": [
{
"bookmarked": {
"order": "desc"
}
},
{
"created_at": {
"order": "desc"
}
}
],
"facets": {},
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"car_id": "78778"
}
},
{
"range": {
"created_at": {
"gte": "2015-04-12T04:00:00.000Z",
"lte": "2015-05-13T03:59:59.999Z"
}
}
},
{
"or": [
{
"term": {
"media_url": ""
}
},
{
"term": {
"media_url": null
}
}
]
}
],
"should": [
{
"term": {
"bookmarked": false
}
}
]
}
}
}
},
"aggregations": {
"word_frequencies": {
"terms": {
"field": "text",
"size": 150
}
}
},
"highlight": {
"fields": {
"text": {
"fragment_size": 1500
}
}
}
},
"api": "_search"
}
You can use the missing filter to take care of null value or field itself is missing. You can combine the same with an empty string term to achieve what you want.
{
"or": [
{
"term": {
"media_url": ""
}
},
{
"missing": {
"field": "media_url"
}
}
]
}
Use the above instead of the single term query for "media_url" in the must clause of your Boolean filter.