How to implement the following condition in elasticsearch query? - elasticsearch

I have an index with some documents having a field named "access_type" . It can have 2 values, either "faculty" or "students".
For the documents with "faculty" as the value for "access_type", there will be another field called "faculties" which is a list of faculty name.
So an example document would look like below:
{
"access_type": "faculty",
"faculties": [
"facultyId1",
"facultyId2",
"facultyId3"
]
}
Now if we have two inputs say one is for the access_type and another is for the faculties.
If I get the following input "faculty" and "facultyId4" . First I need to filter out all the documents matching the access type "faculty" and then in the resulting results the "facuultyId4" should search against the field "faculties". Since the "facultyId4" is not in the above document,it should not be considered a hit.
How can I implement this as an elasticsearch query?

POST http://your.elastic.host:9200/index/type/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"access_type": "faculty"
}
},
{
"term": {
"faculties": "facultyId4"
}
}
]
}
}
}
}
}

Hope this will for work.
GET index/type/_search
{
"query": {
"filtered": {
"filter": {
"and": {
"filters": [
{
"query": {
"match": {
"access_type": "faculty"
}
}
},
{
"query": {
"match": {
"faculties": "facultyId4"
}
}
}
]
}
}
}
}
}

Related

Elasticsearch combine term and range query on nested key/value data

I have ES documents structured in a flat data structure using the nested data type, as they accept arbitrary JSON that we don't control, and we need to avoid a mapping explosion. Here's an example document:
{
"doc_flat":[
{
"key":"timestamp",
"type":"date",
"key_type":"timestamp.date",
"value_date":[
"2023-01-20T12:00:00Z"
]
},
{
"key":"status",
"type":"string",
"key_type":"status.string",
"value_string":[
"warning"
]
},
... more arbitrary fields ...
],
}
I've figured out how to query this nested data set to find matches on this arbitrary nested data, using a query such as:
{
"query": {
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{"term": {"doc_flat.key": "status"}},
{"term": {"doc_flat.value_string": "warning"}}
]
}
}
}
}
}
And I figured out how to find documents matching a particular date range:
{
"query": {
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{"term": {"doc_flat.key": "timestamp"}},
{
"range": {
"doc_flat.value_date": {
"gte": "2023-01-20T00:00:00Z",
"lte": "2023-01-21T00:00:00Z"
}
}
}
]
}
}
}
}
}
But I'm struggling to combine these two queries together, in order to search for documents that have a nested documents which match these two conditions:
a doc_flat.key of status, and a doc_flat.value_string of warning
a doc_flat.key of timestamp, and a doc_flat.value_date in a range
Obviously I can't just shove the second set of query filters into the same must array, because then no documents will match. I think I need to go "one level higher" in my query and wrap it in another bool query? But I can't get my head around how that would look.
You tried two nested inside Bool query?
{
"query": {
"bool": {
"filter": [
{
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{
"term": {
"doc_flat.key": "timestamp"
}
},
{
"range": {
"doc_flat.value_date": {
"gte": "2023-01-20T00:00:00Z",
"lte": "2023-01-21T00:00:00Z"
}
}
}
]
}
}
}
}
],
"must": [
{
"nested": {
"path": "doc_flat",
"query": {
"bool": {
"must": [
{
"term": {
"doc_flat.key": "status"
}
},
{
"term": {
"doc_flat.value_string": "warning"
}
}
]
}
}
}
}
]
}
}
}

How to combine must and must_not in elasticsearch with same field

i have elasticsearch 6.8.8, just for an example of my question. I want to create a query that gets me document with "Test" field with value "1", and i don't want to get "Test" field with value of "3", i know that i could write just the first expression without 3 and it will give me one document with value of "1". But i want to know, is there any way, that i can use must and must_not in the same time, on the same field and getting just the value of "1"?
I wrote this basic example to know what i mean:
{
"from": 0,
"query": {
"nested": {
"path": "attributes",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "1"
}
}
}
],
"must_not": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "3"
}
}
}
]
}
}
]
}
}
}
}
}
I use attributes as nested field with key-value field that use mapping as string type.
You'll need to leave out attributes.key:Test in the must_not because it filters out all Tests:
GET combine_flat/_search
{
"from": 0,
"query": {
"nested": {
"inner_hits": {},
"path": "attributes",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"attributes.key": {
"query": "Test"
}
}
},
{
"match": {
"attributes.value": {
"query": "1"
}
}
}
],
"must_not": [
{
"match": {
"attributes.value": {
"query": "3"
}
}
}
]
}
}
]
}
}
}
}
}
Tip: use inner_hits to just return the matched nested key-value pairs as opposed to the whole field.

Search in multiple index , 'query_shard_exception' when fields are not present

I'm trying to search in multiple indexes, but the fields and mapping for each index are different. Like one index is having nested path.
When I'm trying to query on index's I'm getting error for the index which are not having the nested path.
{
"query": {
"bool": {
"should": [
{
"term": {
"a": "good"
}
},
{
"term": {
"a.b": "sample"
}
},
{
"nested": {
"path": "x.y.z",
"query": {
"bool": {
"should": [
{
"term": {
"x.y.z.id.keyword": "test#gamil.com"
}
}
]
}
}
}
}
]
}
}
}
in above the nested path x.y.z is only present for one index.
I tried finding a solution, found ignore_unavailable. But it will ignore the index not having nested path, but I need the document's in that index which matches other condition in the query.
Try the following query by replacing your-index with the name of the index that contains the nested field.
{
"query": {
"bool": {
"should": [
{
"term": {
"a": "good"
}
},
{
"term": {
"a.b": "sample"
}
},
{
"bool": {
"must": [
{
"term": {
"_index": "your-index"
}
},
{
"nested": {
"path": "x.y.z",
"query": {
"bool": {
"should": [
{
"term": {
"x.y.z.id.keyword": "test#gamil.com"
}
}
]
}
}
}
}
]
}
}
]
}
}
}

Elastic Search - Query with dynamic object and wildcard

I have data in the following format:
{ "_id":1,
"s_id":121211,
"data_detail":{
"name":"John",
"phone_number":08089320xxx,
"city":"ABC"
}
}
I need to search data through elastic search which will query where s_id=? and any text which is available in data_detail object. Example s_id=121211 AND ABC. I need wildcard on data_detail object.
Keys for the data_detail object is not fixed.
Thanks in advance.
I would consider using a bool query with multi_match and term query like this. I haven't tested this, but something on these lines should work I guess.
GET test_index/_search
{
"query": {
"nested": {
"path": "data_detail",
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "ABC",
"fields": [
"data_detail.*"
]
}
},
{
"term": {
"s_id": {
"value": "121211"
}
}
}
]
}
}
}
}
}
Solved this by using the following query:
{
"query": {
"bool": {
"must": [
{
"query_string":{
"fields":["data_detail.*"],
"query": "*str*",
"analyze_wildcard":true
}
},
{
"term": {
"s_id": {
"value": "121211"
}
}
}
]
}
}
}

Elasticsearch Array

I have following values in my document.
"ReturnCode": [ "0", "0" ]
"ReturnCode": [ "0", "1" ]
If I search 0,0 it should return 1st document and If I search 0,1 then it should return 2nd document. I am trying with following query but it's not giving correct result. Result must match with all array elements.
GET test/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"terms": { "ReturnCode":[ "0","1"] }
}
]
}
}
}
}
}
Thanks
Terms query is an OR query
GET test/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": { "ReturnCode":"0"}
},
{
"term": { "ReturnCode":"1"}
}
]
}
}
}
}
}
You need to create individual term queries inside the must clause as above

Resources