how to distinct value after query in elasticsearch - elasticsearch

I use elasticsearch like :
{
"query": {
"match_phrase": {
"title": "my title"
}
},
"aggs": {
"unique_title": {
"cardinality": {
"field": "title"
}
}
}
}
i just want to sql
select distinct title from table where title like '%my title%'
the result give me multiple same results, "cardinality" dont worked whit "query"
if you dont understand me, Please forgive my poor English ^_^

Cardinality aggregation calculates the count of distinct values for a field.
Hence the equivalent sql query for the elasticsearch query you wrote would look like:
select count(distinct title) from table where title like '%my title%'
What you need to use is the Terms aggregation for getting the distinct titles.
{
"query": {
"match_phrase": {
"title": "my title"
}
},
"aggs": {
"unique_title": {
"terms": {
"field": "title"
}
}
}
}
And you need to look into the "aggregations" section of the search response to get the distinct values in the "buckets" array.

You can use below query to get expected result:
GET my_index/my_type/_search
{
"from": 0,
"size": 200,
"query": {
"filtered": {
"filter": {
"bool": {
"must": {
"query": {
"wildcard": {
"title": "*my title*"
}
}
}
}
}
}
},
"_source": {
"includes": [
"title"
],
"excludes": []
}
}

Related

Query on multiple range of document

What I want to search is to extract documents among certain range of documents, not the whole documents. I know ids of documents. For example, I want to query matching some sentences with query field - 'pLabel' among the documents ids of which I know via different process. My trial is as below but I got bunch of documents which is different with my expectation.
For example, in such documents as eid1, eid2...etc groups, I want to query filtering out the matching documents out of the groups (eid1, eid2, eid3, ...). Query is shown as below.
How I fix query statement to get the right search result?
{
"query": {
"bool": {
"must": [
{
"query_string": {
"default_field": "pLabel" ,
"query": "search words here"
}
}
] ,
"must_not": [] ,
"should": [
{
"term": {
"eid": "eid1"
}
} ,
{
"term": {
"eid": "eid2"
}
}
]
}
} ,
"size": 0 ,
"_source": [
"eid"
] ,
"aggs": {
"eids": {
"terms": {
"field": "eid" ,
"size": 1000
}
}
}
}
You need to move the should clause of the Doc IDs inside the must clause.
Right now the query can return any document that matches the query_string clause, it'll only prefer docs that matches the Doc IDs.
Also, you should use terms query
{
"query": {
"bool": {
"must": [
{
"query_string": {
"default_field": "pLabel",
"query": "search words here"
}
},
{
"terms": {
"user": ["eid1", "eid2"]
}
}
]
}
},
"size": 0,
"_source": [
"eid"
],
"aggs": {
"eids": {
"terms": {
"field": "eid",
"size": 1000
}
}
}
}

How to aggregate query result in elasticsearch

I am new in elasticsearch. I want elasticsearch result be like following sql query,
select distinct(car_name) from car_master where car_name like '%SUV%'
I am getting result by doing:
{ "query": {
"query_string": {
"fields" : ["car_name"],
"query": "*SUV*"
}
}
}
but I want distinct records.
You are almost there, you simply need to add a terms aggregation on the car_name field:
{
"query": {
"query_string": {
"fields" : ["car_name"],
"query": "*SUV*"
}
},
"aggs": {
"cars": {
"terms": {
"field": "car_name"
}
}
}
}

Elasticsearch - Aggregations on part of bool query

Say I have this bool query:
"bool" : {
"should" : [
{ "term" : { "FirstName" : "Sandra" } },
{ "term" : { "LastName" : "Jones" } }
],
"minimum_should_match" : 1
}
meaning I want to match all the people with first name Sandra OR last name Jones.
Now, is there any way that I can get perform an aggregation on all the documents that matched the first term only?
For example, I want to get all of the unique values of "Prizes" that anybody named Sandra has. Normally I'd just do:
"query": {
"match": {
"FirstName": "Sandra"
}
},
"aggs": {
"Prizes": {
"terms": {
"field": "Prizes"
}
}
}
Is there any way to combine the two so I only have to perform a single query which returns all of the people with first name Sandra or last name Jones, AND an aggregation only on the people with first name Sandra?
Thanks alot!
Use post_filter.
Please refer the following query. Post_filter will make sure that your bool should clause don't effect your aggregation scope.
Aggregations are filtered based on main query as well, but they are unaffected by post_filter. Please refer to the link
{
"from": 0,
"size": 20,
"aggs": {
"filtered_lastname": {
"filter": {
"query": {
"match": {
"FirstName": "sandra"
}
}
},
"aggs": {
"prizes": {
"terms": {
"field": "Prizes",
"size": 10
}
}
}
}
},
"post_filter": {
"bool": {
"should": [{
"term": {
"FirstName": "Sandra"
}
}, {
"term": {
"LastName": "Jones"
}
}],
"minimum_should_match": 1
}
}
}
Running a filter inside the aggs before aggregating on prizes can help you achieve your desired usecase.
Thanks
Hope this helps

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
}
}
}

Elastic search query according to MySQL Group by clause

I am using Elasticsearch I want to write a query for getting unique record on the basis of query and group:
SELECT * from users where name='%john%', age='21', location='New York' group by name
Could you please let me know how to write the query in elasticsearch with query.
It would go something like this. You need a filtered query with a query_string in the query part to match *john* and then two filters in the filter part to match the age and the location. Finally, the grouping is achieved using a terms aggregation.
{
"query": {
"query": {
"query_string": {
"query": "*john*",
"default_field": "name"
}
},
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"age": 21
}
},
{
"term": {
"location": "New York"
}
}
]
}
}
}
},
"aggs": {
"group_by_name": {
"terms": {
"field": "name"
}
}
}
}

Resources