multiple sub query inside one query elasticsearch - elasticsearch

I have index named dictionary , where contains field like keyword,mapped keyword and category filter.
Keyword Mapped Keyowrd Category
------- -------------- --------
apple apple iphone smartphones
apple apple watch smart watches
apple apple ipad tablets
So if user searches for apple, internally the query will search mapped keywords with respective categories as below query.
SELECT * FROM products where (title= "*apple*" AND title="*iphone*" and category="smartphones") OR (title= "*apple*" AND title="*ipad*" and category="tablets") OR (title= "*apple*" AND title="*watch*" and category="smart watches")
Below is the corresponding elastic search query,I have written.
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match" : {
"title" : {
"query" : "apple iphone",
"operator" : "and"
}
}
},
{
"term": {
"category.raw": "smartphones"
}
}
]
}
},
{
"bool": {
"must": [
{
"match" : {
"title" : {
"query" : "apple watch",
"operator" : "and"
}
}
},
{
"term": {
"category.raw": "smartwatch"
}
}
]
}
},
{
"bool": {
"must": [
{
"match" : {
"title" : {
"query" : "apple ipad",
"operator" : "and"
}
}
},
{
"term": {
"category.raw": "tablets"
}
}
]
}
}
],
"minimum_should_match": 1
}
}
}
Is the above query right? Any changes needed in the above query?
Is there any way to get top 10 results of each sub query in elasticsearch by adding some parameter in this query?

Yes, your query looks fine as far as I can tell. "minimum_should_match": 1 isn't really necessary, that's the default behavior.
You might be able to impose that sort of logic using a function_score query (maybe with a script_score), but I think the better way to do that would be to just execute three different queries, and get the results for each. If you want to execute those multiple queries in one request, you can do that using the Multi Search API.

Related

Elasticsearch: How to filter results with a specific word in a value using elasticsearch

I need to add a parameter to my search that filters results containing a specific word in a value. The query is searching for user history records and contains a url key. I need to filter out /history and any other url containing that string.
Here's my current query:
GET /user_log/_search
{
"size" : 50,
"query": {
"match": {
"user_id": 56678
}
}
}
Here's an example of a record, boiled down to just the value we're looking at:
"_source": {
"url": "/history?page=2&direction=desc",
},
How can the parameters of the search be changed to filter out this result.
You can use the filter param of boolean query in Elasticsearch.
if your url field is of type keyword, you can use the below query
{
"query": {
"bool": {
"must": {
"match": {
"user_id": 56678
}
},
"filter": { --> note filter
"term": {
"url": "/history"
}
}
}
}
}
I found a way to solve my specific issue. Instead of filtering on the url I'm filtering on a different value. Here's what I'm using now:
{
"size" : 50,
"query": {
"bool" : {
"must" : {
"match" : { "user_id" : 56678 }
},
"must_not": {
"match" : { "controller": "History" }
}
}
}
}
I'm still going to leave this question open for a while to see if anyone has other ways of solving the original problem.

Elastic Search Multiple Filter values for the same field

Say that I have to filter cars constructors in a Elastic Search Index (ES 7.15), where the field car_maker is mapped to keyword, having it a limited number of possibilities among car makers string names:
{
"mappings": {
"properties": {
"car_maker": {
"type": "keyword"
}
}
}
}
GET /cars/_search
{
"query": {
"bool": {
"filter": [{
"term": {
"car_maker": "Honda"
}
}]
}
}
}
This, along with a matching query will work ok. The filter will not participate to score calculation as desired.
Now I would like to to filter more car makers for that query (let's say a should query):
{
"query": {
"bool": {
"filter" : [
{"term" : { "car_maker" : "Honda"}},
{"term" : { "car_maker" : "Ferrari"}}
]
}
}
}
this is not going to work. I will have any error from ES query engine, but any result too. Of course is always possibile to apply more filters to different fields like car_maker and car_color, but how to do the opposite: apply more values (Honda, Ferrari, etc.) to the same filter field car_maker like in the example above, without conditioning the score calculation?
You might want to try the following filter query:
{
"query" : {
"bool" : {
"filter" : {
"terms" : {
"car_maker" : ["Honda", "Ferrari"]
}
}
}
}
}

Elasticsearch - use a field match to boost only and not to fetch the document

I have a query phrase that needs to match in either of the fields - name, summary or description or the exact match on the name field.
Now, I have one more new field brand. Match in this field should be used only to boost results. Meaning if there is a match only in the brand field, the doc should not be in the result set.
To solve the without brand I have the below query:
query: {
bool: {
minimum_should_match: 1,
should: [
multi_match:{
query : "Cadbury chocklate milk",
fields : [name, summary, description]
},
term: {
name_keyword: {
value: "Cadbury chocklate milk"
}
}
]
}
}
This works fine for me.
How do I fetch the data using the same query but boost docs that have brand:cadbury, without increasing the recall set(match based on brand:cadbury).
Thanks!
Using a bool inside must should work for you.
multi_match has multiple types and for phrase you have to use type:phrase.
{
"query": {
"bool": {
"must": [
{ "bool" :
{ "should" : [ {
"multi_match" :{
"type" : "phrase",
"query" : "Cadbury chocklate milk",
"fields" : ["name", "summary", "description"]
} }, {
"term": {
"name_keyword": {
"value": "Cadbury chocklate milk"
} }
}
]
}
}
],
"should" : {
"term" : {
"brand" : {
"value" : "cadbury"
}
}
}
}
}

Elastic Search MUST + at least one SHOULD in percolator query

Im trying to make suggestions to users based on several factors:
•Suggestions MUST only be students from the same college
•Suggestions MUST match at least one other field
I thought I had it but the problem is this query will return ALL students from the same school regardless of everything else:
PUT /user/.percolator/4
{
"query": {
"bool": {
"must": [
{ "match": { "college":{
"query" : "Oakland University",
"type" : "phrase"
}}}
],
"should": [
{ "match": { "hashtag": "#chipotle" }},
{ "match": { "hashtag": "#running"}},
{ "match": { "college_course": "ART-160" }}
]
}
}
}
POST /user/stuff/_percolate/
{
"doc":{
"college":"Oakland University",
"college_course": "WRT BIO MTH-400"
}
}
This is because the behavior of should and must in the same bool query. By default none of the "should" clauses are required to match, unless your bool contains only the "should" clause then it's required to match at least one.
To solve you problem, you just need to add "minimum_should_match" : 1 inside your bool query :)

Elasticsearch DSL query from an SQL statement

I'm new to Elasticsearch. I don't think I fully understand the concept of query and filters. In my case I just want to use filters as I don't want to use advance feature like scoring.
How would I convert the following SQL statement into elasticsearch query?
SELECT * FROM advertiser
WHERE company like '%com%'
AND sales_rep IN (1,2)
What I have so far:
curl -XGET 'localhost:9200/advertisers/advertiser/_search?pretty=true' -d '
{
"query" : {
"bool" : {
"must" : {
"wildcard" : { "company" : "*com*" }
}
}
},
"size":1000000
}'
How to I add the OR filters on sales_rep field?
Thanks
Add a "should" clause after your must clause. In a bool query, one or more should clauses must match by default. Actually, you can set the "minimum_number_should_match" to be any number, Check out the bool query docs.
For your case, this should work.
"should" : [
{
"term" : { "sales_rep_id" : "1" }
},
{
"term" : { "sales_rep_id" : "2" }
}
],
The same concept works for bool filters. Just change "query" to "filter". The bool filter docs are here.
I come across this post 4 years too late...
Anyways, perhaps the following code could be useful...
{
"query": {
"filtered": {
"query": {
"wildcard": {
"company": "*com*"
}
},
"filter": {
"bool": {
"should": [
{
"terms": {
"sales_rep_id": [ "1", "2" ]
}
}
]
}
}
}
}
}

Resources