ElasticSearch aggs with function_score - elasticsearch

I'm trying to exclude duplicated documents which have the same slug parameters to do it I use aggs in ElasticSearch (version 2.4). I use - this query:
{
"fields":[
"id",
"score"],
"size":0,
"query":{
"function_score":{
"query":{
"bool":{
"should":[
{
"match":{
"main_headline.en":{
"query":"headline_for_search"
}
}
},
{
"match":{
"body.en":"body for search"
}
}],
"must_not":{
"term":{
"id":75333
}
},
"filter":[
{
"term":{
"status":3
}
},
[
{
"term":{
"sites":6
}
}]]
}
},
"functions":[
{
"gauss":{
"published_at":{
"scale":"140w",
"decay":0.3
}
}
}
]
},
"aggs":{
"postslug":{
"terms":{
"field":"slug",
"order":{
"top_score":"desc"
}
},
"aggs":{
"grouppost":{
"top_hits": {
"_source": {
"include": [
"id",
"slug",
]
},
"size" : 10
}
}
}
}
}
}
}
When I run it I get error
failed to parse search source. expected field name but got [START_OBJECT]
I can`t figure out where is a mistake.
Without section aggs all works fine (except present duplicates)

I see one issue which relates to the fact that in the source filtering section include should read includes. Also, the aggs section is not at the right location, you have it in the query section, and it should be at the top-level:
{
"fields": [
"id",
"score"
],
"size": 0,
"query": {
"function_score": {
"query": {
"bool": {
"should": [
{
"match": {
"main_headline.en": {
"query": "headline_for_search"
}
}
},
{
"match": {
"body.en": "body for search"
}
}
],
"must_not": {
"term": {
"id": 75333
}
},
"filter": [
{
"term": {
"status": 3
}
},
[
{
"term": {
"sites": 6
}
}
]
]
}
},
"functions": [
{
"gauss": {
"published_at": {
"scale": "140w",
"decay": 0.3
}
}
}
]
}
},
"aggs": {
"postslug": {
"terms": {
"field": "slug",
"order": {
"top_score": "desc"
}
},
"aggs": {
"grouppost": {
"top_hits": {
"_source": {
"includes": [
"id",
"slug"
]
},
"size": 10
}
}
}
}
}
}

Related

Source filtering an array of objects in ElasticSearch

Here is a document in ElasticSearch
"CompanyId": 5733,
"PartNumber": "W8S038",
"Name_en": "#8 Washer, M4 Compatible, Stainless Steel, Pack of 100",
"ProductId": 90023,
"CompanyName": "Washers Ltd",
"Prices": [
{
"BuyerId": 308,
"Price": 2.42
}
,
{
"BuyerId": 406,
"Price": 2.22
}
]
}
Obviously we can't let on to buyer 308 that buyer 406 is getting a better price. Therefore when buyer 308 is searching I need to remove all of the prices for other buyers.
I'd like to do this by using source filtering. But how?!
(I could exclude Prices and add back in the required price by using a script_field. However, that means that the price is not part of the source document and therefore ReactiveSearch can't see it and therefore can't sort on it.)
Update: here is the query generated by ReactiveSearch to which I need to append the limit on prices:
"query":{
"bool":{
"must":[
{
"bool":{
"must":[
{
"bool":{
"must":[
{
"bool":{
"should":[
{
"multi_match":{
"query":"m4 washer",
"fields":[
"Name_en"
],
"type":"cross_fields",
"operator":"and"
}
},
{
"multi_match":{
"query":"m4 washer",
"fields":[
"Name_en"
],
"type":"phrase_prefix",
"operator":"and"
}
}
],
"minimum_should_match":"1"
}
}
]
}
}
]
}
}
],
"filter": [
{
"nested": {
"path": "Prices",
"query": {
"term": {
"Prices.CompanyId": 1474
}
},
"inner_hits": {}
}
}
]
}
},
"size":10,
"aggs":{
"CompanyName.raw":{
"terms":{
"field":"CompanyName.raw",
"size":1000,
"order":{
"_count":"desc"
}
}
}
},
"_source":{
"excludes":[
"PurchasingViews",
"ContractFilters",
"SearchField*",
"Keywords*",
"Menus*"
]
},
"from":0,
"sort":[
{
"Name_en.raw":{
"order":"asc"
}
}
],
"script_fields":{
"price":{
"script":{
"lang":"painless",
"inline":"if(params['_source']['Prices'] != null){for(p in params['_source']['Prices']){ if(p.CompanyId == 1474) return p.Price; }} return null;"
}
}
}
}
(That bool, must, bool, must, bool, must, bool, should seems rather stupid?)
You need to use the nested inner_hits feature like below.
{
"_source": [
"CompanyId", "PartNumber", "Name_en", "ProductId", "CompanyName"
],
"query": {
"bool": {
"filter": [
{
"nested": {
"path": "Prices",
"query": {
"term": {
"Prices.BuyerId": 308
}
},
"inner_hits": {}
}
}
]
}
}
}
In the output you'll get exactly what you expect, namely all the root-level fields and the matching prices for the given buyer.
UPDATE:
Here is how I would rewrite your query:
{
"query": {
"bool": {
"minimum_should_match": "1",
"should": [
{
"multi_match": {
"query": "m4 washer",
"fields": [
"Name_en"
],
"type": "cross_fields",
"operator": "and"
}
},
{
"multi_match": {
"query": "m4 washer",
"fields": [
"Name_en"
],
"type": "phrase_prefix",
"operator": "and"
}
}
],
"filter": [
{
"nested": {
"path": "Prices",
"query": {
"term": {
"Prices.CompanyId": 1474
}
},
"inner_hits": {}
}
}
]
}
},
"size": 10,
"aggs": {
"CompanyName.raw": {
"terms": {
"field": "CompanyName.raw",
"size": 1000,
"order": {
"_count": "desc"
}
}
}
},
"_source": {
"excludes": [
"PurchasingViews",
"ContractFilters",
"SearchField*",
"Keywords*",
"Menus*",
"Prices"
]
},
"from": 0,
"sort": [
{
"Name_en.raw": {
"order": "asc"
}
}
],
"script_fields": {
"price": {
"script": {
"lang": "painless",
"inline": "if(params['_source']['Prices'] != null){for(p in params['_source']['Prices']){ if(p.CompanyId == 1474) return p.Price; }} return null;"
}
}
}
}

elasticsearch nested query, more than one one object should meet conditions

I have some questions about nested query.
Here is my example. The mapping is {"user":"nested"}.The exist data just like this:
{
"user": [
{
"first":"John",
"last":"Smith"
},
{
"first":"Alice",
"last":"White"
}
]
}
How do I create a query to find this document that meets all the conditions:
the first object of user that its "first" is "John" and "last" is "Smith";
the second object of user that its "first" is "Alice" and "last" is "White"
Try with below query :
{
"query":{
"bool":{
"filter":[
{
"bool":{
"must":[
{
"bool":{
"must":[
{
"nested":{
"query":{
"bool":{
"must":[
{
"match_phrase":{
"user.first":{
"query":"John"
}
}
},
{
"match_phrase":{
"user.last":{
"query":"Smith"
}
}
}
]
}
},
"path":"user"
}
},
{
"nested":{
"query":{
"bool":{
"must":[
{
"match_phrase":{
"user.first":{
"query":"Alice"
}
}
},
{
"match_phrase":{
"user.last":{
"query":"White"
}
}
}
]
}
},
"path":"user"
}
}
]
}
}
]
}
}
]
}
}
}
Below query is what you are looking for. You simply need to have two nested queries, one for each conditions you've mentioned, combined in a bool using must clause.
Note that I'm assuming that the fields user.first and user.last are of text type having standard analyzer
POST <your_index_name>
{
"query":{
"bool":{
"must":[
{
"nested":{
"path":"user",
"query":{
"bool":{
"must":[
{
"match":{
"user.first":"john"
}
},
{
"match":{
"user.last":"smith"
}
}
]
}
}
}
},
{
"nested":{
"path":"user",
"query":{
"bool":{
"must":[
{
"match":{
"user.first":"alice"
}
},
{
"match":{
"user.last":"white"
}
}
]
}
}
}
}
]
}
}
}
Hope this helps!
The answer is:
{
"query": {
"bool": {
"must": [
{
"has_parent": {
"parent_type": "doc",
"query": {
"bool": {
"must": [
{
"terms": {
"id": [
713
]
}
},
{
"range": {
"created": {
"lte": "now/d"
}
}
},
{
"range": {
"expires": {
"gte": "now/d"
}
}
}
]
}
}
}
},
{
"nested": {
"path": "prices",
"query": {
"bool": {
"filter": [
{
"term": {
"prices.id_prcknd": 167
}
}
]
}
}
}
},
{
"term": {
"doc_type": "item"
}
},
{
"bool": {
"should": [
{
"term": {
"have_prices": true
}
},
{
"term": {
"is_folder": true
}
}
]
}
}
],
"must_not": {
"exists": {
"field": "folder"
}
}
}
},
"sort": [
{
"is_folder": {
"order": "desc"
}
},
{
"title_low.order": {
"order": "asc"
}
}
],
"size": 1000
}

Elastic Search error in complex bool query

I am trying to make an elasticsearch query where, I need to search for a time frame in the elasticsearch table. I have records which has startime and endtime. And from UI I am giving a starttime and endtime which is time windows for which I need to search files for. Assuming the time window of starttime and endtime in the records is smaller than the time window entered by user, I have created the following query:
{
"_source":["filename","starttime","endtime"],
"sort":[{
"starttime":{"order":"asc"}
}],
"query":{
"bool":{
"should":{
"bool":{
"must":[
"range":{
"starttime":{
"lte":1489602610000
}
},
"range":{
"endtime":{
"gte":1489602610000,
}
}
]
}
},
"should":{
"bool":{
"must":[
"range":{
"starttime":{
"gte":1489602610000
}
},
"range":{
"endtime":{
"lte":1489689000000
}
}
]
}
},
"should":{
"bool":{
"must":[
"range":{
"starttime":{
"lte":1489689000000
}
},
"range":{
"endtime":{
"gte":1489689000000
}
}
]
}
}
}
}
}
I am getting error
"Unexpected character (':' (code 58)): was expecting comma to separate
Array entries\n at [Source:
org.elasticsearch.transport.netty4.ByteBufStreamInput#29263f09; line:
11, column: 33]"
There are several issues with your query:
one dangling comma
more than one bool/should clauses
range queries not properly wrapped inside curly braces
You can find the correct query below:
{
"_source": [
"filename",
"starttime",
"endtime"
],
"sort": [
{
"starttime": {
"order": "asc"
}
}
],
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"range": {
"starttime": {
"lte": 1489602610000
}
}
},
{
"range": {
"endtime": {
"gte": 1489602610000
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"starttime": {
"gte": 1489602610000
}
}
},
{
"range": {
"endtime": {
"lte": 1489689000000
}
}
}
]
}
},
{
"bool": {
"must": [
{
"range": {
"starttime": {
"lte": 1489689000000
}
}
},
{
"range": {
"endtime": {
"gte": 1489689000000
}
}
}
]
}
}
]
}
}
}

How to query a nested object with combined AND and OR logic?

How should this expression be written as a query:
(attributes.id = 14 OR attributes.id = 15) AND (attributes.id = 4843 OR attributes.id = 4859)
The nested object looks like this:
{
"attributes":[
{
"id":14,
"type":"color",
"name":"Sort",
"version":1
},
{
"id":15,
"type":"color",
"name":"Sølv",
"version":1
},
{
"id":2031,
"type":"brand",
"name":"Jimmy Choo",
"version":1
},
{
"id":4843,
"type":"size",
"name":"36x28",
"version":1
},
{
"id":4859,
"type":"size",
"name":"38x36",
"version":1
},
{
"id":4927,
"type":"size",
"name":"60J",
"version":1
},
{
"id":4958,
"type":"size",
"name":"75F",
"version":1
}
]
}
I've tried using this query - among many - without any luck:
{
"query":{
"nested":{
"path":"attributes",
"query":{
"bool":{
"should":[
{
"terms":{
"attributes.id":[
14,
15
]
}
},
{
"terms":{
"attributes.id":[
4843,
4859
]
}
}
],
"minimum_should_match":2
}
}
}
}
}
The above query returns zero results.
Any help would be appreciated.
{
"query":{
"nested":{
"path":"attributes",
"query":{
"bool":{
"must":[{
"bool": {
"should": [
{
"term": {
"attributes.id": 14
}
},{
"term": {
"attributes.id": 15
}
}
]
}
},{
"bool": {
"should": [
{
"term": {
"attributes.id": 4843
}
},{
"term": {
"attributes.id": 4859
}
}
]
}
}
]
}
}
}
This should work.
I got the answer on Elastic Stack by Daniel_Penning:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "variants.attributes",
"query": {
"terms": {
"variants.attributes.id": [
14, 15
]
}
}
}
},
{
"nested": {
"path": "variants.attributes",
"query": {
"terms": {
"variants.attributes.id": [
4843, 4859
]
}
}
}
}
]
}
}
}

Elasticsearch Query for getting field with 'AND' relation

I'm having elastic document as below
I want a search query satisfying condition:
how to get the those OPERATIONS and CATEGORY values that has both AREA=Mumbai and AREA=Chennai
So Output should be CATEGORY:Consulting1 , OPERATIONS: Regulatory Operations
Use terms Query :
{
"query": {
"terms": {
"AREA": [
"Mumbai",
"Chennai"
]
}
}
}
May be that works:
{
"query": {
"bool": {
"must": [
{"term": { "AREA" : "Mumbai" }},
{"term": { "AREA" : "Chennai" }}
]
}
}
}
Try this and let me know:
{
"size": 0,
"query": {
"bool": {
"should": [
{
"term": {
"AREA": "mumbai"
}
},
{
"term": {
"AREA": "chennai"
}
}
]
}
},
"aggs": {
"unique_operations": {
"terms": {
"field": "OPERATIONS",
"size": 10
},
"aggs": {
"count_areas": {
"cardinality": {
"field": "AREA"
}
},
"top": {
"top_hits": {
"size": 2,
"_source": {
"include": ["CATEGORY"]
}
}
},
"areas_bucket_filter": {
"bucket_selector": {
"buckets_path": {
"areasCount": "count_areas"
},
"script": "areasCount == 2"
}
}
}
}
}
}
LATER EDIT: added top_hits aggregation to get back sample documents covering the request for the categories.
Please try this one.
{
"query": {
"bool": {
"should": [
{
"query_string": {
"default_field": "AREA",
"query": "mumbai"
}
},
{
"query_string": {
"default_field": "AREA",
"query": "chennai"
}
}
]
}
}
}[![result][1]][1]

Resources