Elasticsearch matched results on top and remaining after them - elasticsearch

I am using elasticsearch in my application and I am new to Elasticsearch.
I have an index called files with some tags associated to it. I want to query them using tags. something like this may be
{
"query": {
"terms": {
"tags": [
"xxx",
"yyy"
]
}
},
"sort": [
{
"created_at": {
"order": "desc"
}
}
]
}
The above query results only matched ones. But I need all the results with matched results on top. And also sort by created_at. How to do it?
I TRIED THIS:
{
"query": {
"bool": {
"should": [
{
"terms": {
"name": [
"cool",
"co"
]
}
}
],
"minimum_should_match": 0
}
},
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"created_at": {
"order": "desc"
}
}
]
}
But results zero always.

You can use bool queries with should.
Since you want all the docs, you can use a match_all. should only affects the scoring and not whether documents are included or not.
{
"query": {
"bool": {
"must" :
{
"match_all": { }
}
},
"should": [
{ "terms" : {
"tags": [
"xxx",
"yyy"
]
} }]
},
"sort": [
{ "_score":
{ "order": "desc"
}
},
{ "created_at":
{ "order": "desc"
}
}
]
}
Also, sort can take an array so you can pass in your multiple parameters basis which the results should be sorted.

Related

How to get the latest record from each unique value of key

How to get the latest record from each unique value of key combined (in the example which is “combined.keyword”)
I can see the buckets in aggregations, but also wanted a way to get the most recent record for each bucket.
Here is my query:
GET /new_csvindex/_search?pretty
{
"size" : 1,
"query": {
"bool" : {
"must_not":[
{"term": {"combined.keyword" : "combined"}}
]
}
},
"sort": [
{ "#timestamp": { "order": "desc" }}
],
"aggs" : {
"get_the_latest_record_from_each_bucket" : {
"terms" : { "field" : "combined.keyword", "exclude": [ "combined"]}
}
}
}
You are probably looking for top_hits aggregation. Use it as below:
{
"size": 1,
"query": {
"bool": {
"must_not": [
{
"term": {
"combined.keyword": "combined"
}
}
]
}
},
"sort": [
{
"#timestamp": {
"order": "desc"
}
}
],
"aggs": {
"get_the_latest_record_from_each_bucket": {
"terms": {
"field": "combined.keyword",
"exclude": [
"combined"
]
},
"aggs": {
"latest": {
"top_hit": {
"sort": {
"#timestamp": "desc"
},
"size": 1
}
}
}
}
}
}

How to write a conditional in a search query?

I am searching among documents in a particular district. Documents have various statuses. The aim is to return all documents, except when document's status code is ABCD - such documents should only be returned if their ID is greater than 100. I have tried writing multiple queries, including the one below, which returns only the ABCD documents with ID greater than 100, and none of the other documents. What is wrong here? How can I get the non-ABCD documents as well?
"_source": true,
"from": 0,
"size": 50,
"sort": [
{
"firstStamp": "DESC"
}
],
"query": {
"bool": {
"must": [
{
"term": {
"districtId": "3755"
}
},
{
"bool": {
"must": [
{
"terms": {
"documentStatus.code.keyword": [
"ABCD"
]
}
},
{
"bool": {
"must": {
"script": {
"script": "doc['id'].value > 100"
}
}
}
}
]
}
}
]
}
}
}```
Since you have not added any index mapping, looking at your search
query data seems to be of object field data type. As far as I can
understand, your aim is to return all documents, except when the
document's status code is ABCD and document with status code ABCD
should only be returned if their ID is greater than 100.
Adding a working example with index data, search query, and search result
Index Data:
{
"id":200,
"documentStatus":{
"code":"DEF"
}
}
{
"id":200,
"documentStatus":{
"code":"ABCD"
}
}
{
"id":100,
"documentStatus":{
"code":"ABCD"
}
}
Search Query:
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"terms": {
"documentStatus.code.keyword": [
"ABCD"
]
}
},
{
"bool": {
"must": {
"script": {
"script": "doc['id'].value > 100"
}
}
}
}
]
}
},
{
"bool": {
"must_not": {
"terms": {
"documentStatus.code.keyword": [
"ABCD"
]
}
}
}
}
]
}
}
}
Search Result:
"hits": [
{
"_index": "stof_64351595",
"_type": "_doc",
"_id": "2",
"_score": 2.0,
"_source": {
"id": 200,
"documentStatus": {
"code": "ABCD"
}
}
},
{
"_index": "stof_64351595",
"_type": "_doc",
"_id": "3",
"_score": 0.0,
"_source": {
"id": 200,
"documentStatus": {
"code": "DEF"
}
}
}
]
You need to use must_not in your query if you want to have documents which don't have status code = ABCD. So your query would be some thing like this:
"from": 0,
"size": 50,
"sort": [
{
"firstStamp": "DESC"
}
],
{
"query": {
"bool": {
"must": [
{
"term": {
"districtId": "3755"
}
},
{
"range": {
"id": {
"gt": 100
}
}
}
],
"must_not": [
{
"terms": {
"documentStatus.code.keyword": [
"ABCD"
]
}
}
]
}
}
}

use wildcard with Terms in elasticsearch

I wanted to simulate SQL's IN so I used terms filter, but terms does not support wild cards like adding astrisck in "*egypt*".
so how can i achieve the following query?
PS: i am using elastica
{
"query": {
"bool": {
"should": [
{
"terms": {
"country_name": [
"*egypt*",
"*italy*"
]
}
}
]
}
},
"sort": [
{
"rank": {
"order": "desc"
}
}
]
}
terms query does not support wildcards. You can use match or wildcard query instead. If your problem is multiple values to filter you can combine queries inside should, so it will look like this
{
"query": {
"bool": {
"should": [
{
"wildcard": {
"country_name": "*egypt*"
}
},
{
"wildcard": {
"country_name": "*italy*"
}
}
]
}
},
"sort": [
{
"rank": {
"order": "desc"
}
}
]
}

How to query multiple parameters in a nested field in elasticsearch

I'm trying to search for keyword and then add nested queries for amenities which is a nested field of an array of objects.
With the query below I am able to search when I'm only matching one amenity id but when I have more than one it doesn't return anything.
Anyone have an idea what is wrong with my query ?
{
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"_geo_distance": {
"geolocation": [
100,
10
],
"order": "asc",
"unit": "m",
"mode": "min",
"distance_type": "sloppy_arc"
}
}
],
"query": {
"bool": {
"must": [
{
"multi_match": {
"fields": [
"name^2",
"city",
"state",
"zip"
],
"fuzziness": 5,
"query": "complete"
}
},
{
"nested": {
"path": "amenities",
"query": {
"bool": {
"must": [
{
"term": {
"amenities.id": "1"
}
},
{
"term": {
"amenities.id": "2"
}
}
]
}
}
}
}
]
}
}
}
When you do:
"must": [
{
"term": {
"amenities.id": "1"
}
},
{
"term": {
"amenities.id": "2"
}
}]
What you're actually saying is find me any document where "amenities.id"="1" and "amenities.id"="2" which unless "amenities.id" is a list of values it won't work.
What you probably want to say is find me any document where "amenities.id"="1" or "amenities.id"="2"
To do that you should use should instead of must:
"should": [
{
"term": {
"amenities.id": "1"
}
},
{
"term": {
"amenities.id": "2"
}
}]

Filtered aggregation query error

I am trying to run a filtered aggregation like below but getting error.
"Unknown key for a START_OBJECT in [associations]: [disabledDate]. Can anyone review the query and suggest any changes required.
STEPS in the query:
1. Query all documents with versionDate less than or equal to the given
date.
2. Aggregate on Id.
3. Run a subaggregation top hits query with missing disabledDate filter.
4. apply post filter for missing disabledDate.
{
"query": {
"bool": {
"must": [
{
"range": {
"versionDate": {
"from": null,
"to": "2016-05-25T20:53:22.742Z",
"include_lower": false,
"include_upper": true
}
}
},
{
"terms": {
"domainId": [
"yy"
]
}
},
{
"terms": {
"termId": [
"rr"
]
}
}
]
}
},
"aggregations": {
"associations": {
"terms": {
"field": "id",
"size": 0,
"execution_hint": "global_ordinals_low_cardinality",
"order": {
"_term": "asc"
},
"disabledDate": {
"filters": {
"missing": {
"field": "disbaledDate"
}
},
"aggregations": {
"top": {
"top_hits": {
"size": 1,
"_source": {
"includes": [],
"excludes": []
},
"sort": [
{
"versionDate": {
"order": "desc"
}
}
]
}
}
}
}
}
}
},
"post_filter": {
"missing": {
"field": "disabledDate"
}
}
}

Resources