Can a single field take multiple queries in elasticsearch, using "multi_match"? - elasticsearch

I'm trying to work with queries in elasticsearch.
{
"query":{
"bool":{
"should":[
{
"multi_match":{
"query":"History",
"fields":[
"service_category.keyword"
]
}
},
{
"terms":{
"company_id":[
"6"
]
}
}
]
}
}
}
Here it is my query.
The result is: All fields that takes service_category=History and all service_category that have company_id = 6.
Now I want to change the result to: All fields that takes service_category=History & company_id=2 also service_categories with company_id = 6.
I want my answer to be something like :
(service_category.keyword:History AND company_id:2)AND (company_id:6)

I suppose you could go with:
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"multi_match": {
"query": "History",
"fields": [ "service_category.keyword" ]
}
},
{
"terms": {
"company_id": [ "2" ]
}
}
]
}
},
{
"terms": {
"company_id": [ "6" ]
}
}
]
}
}
}
which can be understood as:
(service_category.keyword:History AND company_id:2) OR (company_id:6)

Related

Elasticsearch query to filter document by specific field value with conditions

I want to filter brand names if supplied but return all brands if the filter is empty.
here is my query.
"query": {
"bool": {
"must": [
{
"terms": {
"seller": [
"Seller1",
"Seller2"
]
}
},
{
"bool": {
"should": [
{
"terms": {
"brand": [
"brand1"
]
}
},
{
"bool": {
"must_not": [
{
"term": {
"brand": {
"value": ""
}
}
}
]
}
}
]
}
},
{
"nested": {
"path": "Stock",
"query": {
"bool": {
"must": {
"match": {
"region": "Regional"
}
},
"filter": [
{
"term": {
"pincode": "12345"
}
}
]
}
}
}
}
]
}
}
I want if (brand == ["brand1","brand2"]) return those brand products only. But if supplied empty return all. I tried to use it with should, still getting everything if brand is supplied.
There are multipul ways and some of are mentioned below:
Option 1:
You can handle this logic of include, exclude at the application level while creating queries. If you are using Java or python client then it is easily achievable. If you are calling direct search API of elasticsearch then you can not add brand term clause while calling api.
Option 2:
You can use the search template functionality of Elasticsearch.
First you need to create search template as shown in below example:
PUT _scripts/my-search-template
{
"script": {
"lang": "mustache",
"source": """{
"query": {
"bool": {
"must": [
{
"terms": {
"seller": [
"seller1",
"seller2"
]
}
}
],
"filter": [
{{#filter}}
{
"terms": {
"{{name}}":
{{#toJson}}value{{/toJson}}
}
}{{/filter}}
]
}
}
}"""
}
}
You can use below API to search using search template, here if you dont pass brand in filter it will not add in actual query:
POST querycheck/_search/template
{
"id": "my-search-template",
"params": {
"filter": [
{
"name": "brand",
"value": [
"brand1",
"brand2"
]
}
]
}
}
You can use render api as well to check if query template is generating query correct or not.
POST _render/template
{
"id": "my-search-template",
"params": {
"filter": [
{
"name": "brand",
"value": [
"brand1",
"brand2"
]
}
]
}
}

nested boolean with match query in elasticsearch

I would like to match within a boolean query in Elasticsearch. I have the match query and boolean query working as expected now, but I am not sure how to have a AND to combine them.
nested boolean
{
"query": {
"constant_score" : {
"filter":{
"bool":{
"must":[
{"terms":{"address.keyword": addr}},
{"bool":{
"should":[
{"terms": {"state.keyword": state}}
,{"terms": {"city.keyword": city}}
]
}}
]
}
}
}}}
match
{"query": {
"match": {
"auct_title": {
"query": keyword,
"operator": "and"
}
}
}
, "collapse" : {
"field" : "id"
}
,"sort" : [
{ sort_field: {"order" : sort_order} }]
,"size":20
}
You can move natch to the must clause . So document has to satisfy three conditions
1.address
2.either of state/city
2.match on auct_title
It will then return one document per Id based on sort order passed
GET <index>/_search
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must": [
{
"term": {
"address.keyword": "addr"
}
},
{
"bool": {
"should": [
{
"term": {
"state.keyword": "state"
}
},
{
"term": {
"city.keyword": "city"
}
}
]
}
},
{
"match": {
"auct_title": {
"query": "keyword",
"operator": "and"
}
}
}
]
}
}
}
},
"collapse": {
"field": "id"
},
"sort": [
{
"FIELD": {
"order": "desc"
}
}
],
"size": 20
}

ElasticSearch aggs with function_score

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

How to use multi_match with indices in elasticsearch?

I have 2 indices USER and URL. I want to run a query on different fields based on the index.
In USER index, query should search in name and id field.
But in URL search has to be performed on title and id field.
POST /_search
{
"query":{
"indices":[
{
"indices":[
"URL"
],
"query":{
"multi_match":{
"query":"SMU ",
"fields":[
"title",
"id"
]
}
}
},
{
"indices":[
"USER"
],
"query":{
"multi_match":{
"query":"SMU ",
"fields":[
"name",
"id"
]
}
}
}
]
}
}
The above query is not working. What is the change required to make it work.
How can I merge multi_match search with indices search?
The indices query is deprecated in ES 5, but it still works, you just have a bad structure in yours, i.e. you need to put each indices query in a bool/filter clause.
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"indices": {
"indices": [
"URL"
],
"query": {
"multi_match": {
"query": "SMU ",
"fields": [
"title",
"id"
]
}
}
}
},
{
"indices": {
"indices": [
"USER"
],
"query": {
"multi_match": {
"query": "SMU ",
"fields": [
"name",
"id"
]
}
}
}
}
]
}
}
}
Since the indices query is deprecated, the new idea is to use a simple term query on the _index field instead. Try this:
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"filter": [
{
"term": {
"_index": "URL"
}
},
{
"multi_match": {
"query": "SMU ",
"fields": [
"title",
"id"
]
}
}
]
}
},
{
"bool": {
"filter": [
{
"term": {
"_index": "USER"
}
},
{
"multi_match": {
"query": "SMU ",
"fields": [
"name",
"id"
]
}
}
]
}
}
]
}
}
}

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 tablename where (name="d" and time>1231312) or (name="ds" and time>21)
{
"filter" : {
"or":[
{ "and" : [
{"range": {"time": {"gt": 1231312}}},
{"term" : {"name":"d"}}
]},
{ "and" : [
{"range": {"time": {"gt": 21}}},
{"term" : {"name":"ds"}}
]}
]
}
}
Here is the query DSL which is equivalent to your sql query. The query_string/query filter is not cached by default that's why I have use _cache:true performance wise it will works good.
curl -XPOST http://localhost:9200/index_name/_search '{
"filter": {
"or": {
"filters": [
{
"fquery": {
"query": {
"bool": {
"must": [
{
"term": {
"name": "d"
}
},
{
"range": {
"time": {
"gte":1231312
}
}
}
]
}
},
"_cache": true
}
},
{
"fquery": {
"query": {
"bool": {
"must": [
{
"term": {
"name": "ds"
}
},
{
"range": {
"time": {
"gte":21
}
}
}
]
}
},
"_cache": true
}
}
]
}
}
}'

Resources