How to search for separate key and value fields in an array in ElasticSearch? - elasticsearch

My ElasticSearch documents contain a nested collection of form fields. Each field has a name and a value and the mapping is as follows:
form: {
properties: {
id: { type: 'integer' },
name: { type: 'text' },
form_data: {
type: 'nested',
properties: {
'name': { type: 'keyword' },
'value': { type: 'text', analyzer: 'full_text_analyzer' }
}
}
}
}
I need to allow the user to search for multiple form fields to refine their search. They can choose which fields to search by and assign a value to each. For example
applicant_name = 'Joe'
pet_type = 'dog'
This would find all documents that contained a field named applicant_name which had a value fuzzy matching Joe as well as a field named pet_type and a value fuzzy matching dog.
The query I'm trying to do this with is as follows.:
{
"query": {
"bool": {
"must": [{
"nested": {
"path": "form_data",
"query": {
"filter": {
"bool": {
"must": [
{
"bool": {
"must": [
{ "term": { "form_data.name": "applicant_name" } },
{ "match": { "form_data.value": "Joe" } }
]
}
},
{
"bool": {
"must": [
{ "term": { "form_data.name": "pet_type" } },
{ "match": { "form_data.value": "dog" } }
]
}
}
]
}
}
}
}
}]
}
}
}
However, I get 0 results.

Try using a nested query per condition in your initial "must" clause:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "form_data",
"query": {
"bool": {
"must": [
{ "term": { "form_data.name": "applicant_name" } },
{ "match": { "form_data.value": "Joe" } }
]
}
}
}
},
{
"nested": {
"path": "form_data",
"query": {
"bool": {
"must": [
{ "term": { "form_data.name": "pet_type" } },
{ "match": { "form_data.value": "dog" } }
]
}
}
}
}
]
}
}
}

Related

Sql query on elastic 6.8 does not work as expected. Array of nested objects are flattened same as of type object

Thanks for the answer in advance.
I am running a query
SELECT key
FROM records_index
WHERE
(product_nested_field.code = '1234' and product_nested_field.codeset = 'category1' OR product_nested_field.code = '444' and product_nested_field.codeset = 'category1')
AND (role_name IN ('user', 'admin'))
GROUP BY records_uuid
In records_index I have record with two products
[
{codeset: category1, code:444},
{codeset: category2, code:1234}
]
The problem is that query does find a specified record.
such behavior is expected for "type": "object" but why I am getting that result for product_nested_field of type nested?
when I translate SQL to JSON I am getting
{
"bool": {
"must": [
{
"bool": {
"must": [
{
"nested": {
"query": {
"term": {
"product_nested_field.codeset": {
"value": "category1"
}
}
}
}
}
]
}
},
{
"bool": {
"must": [
{
"bool": {
"should": [
{
"nested": {
"query": {
"term": {
"product_nested_field.code": {
"value": "1234"
}
}
}
}
},
{
"nested": {
"query": {
"term": {
"product_nested_field.code": {
"value": "444"
}
}
}
}
}
]
}
}
]
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
}
why elastic moves product_nested_field.codeset = 'category1' into separate nested query.

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

Match multiple properties on the same nested document in ElasticSearch

I'm trying to accomplish what boils down to a boolean AND on nested documents in ElasticSearch. Let's say I have the following two documents.
{
"id": 1,
"secondLevels": [
{
"thirdLevels": [
{
"isActive": true,
"user": "anotheruser#domain.com"
}
]
},
{
"thirdLevels": [
{
"isActive": false,
"user": "user#domain.com"
}
]
}
]
}
{
"id": 2,
"secondLevels": [
{
"thirdLevels": [
{
"isActive": true,
"user": "user#domain.com"
}
]
}
]
}
In this case, I want to only match documents (in this case ID: 2) that have a nested document with both isActive: true AND user: user#domain.com.
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "secondLevels.thirdLevels",
"query": {
"bool": {
"must": [
{
"term": {
"secondLevels.thirdLevels.isActive": true
}
},
{
"term": {
"secondLevels.thirdLevels.user": "user#domain.com"
}
}
]
}
}
}
}
]
}
}
}
However, what seems to be happening is that my query turns up both documents because the first document has one thirdLevel that has isActive: true and another thirdLevel that has the appropriate user.
Is there any way to enforce this strictly at query/filter time or do I have to do this in a script?
With nested-objects and nested-query, you have made most of the way.
All you have to do now is to add the inner hits flag and also use source filtering for move entire secondLevels documents out of the way:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "secondLevels.thirdLevels",
"query": {
"bool": {
"must": [
{
"term": {
"secondLevels.thirdLevels.isActive": true
}
},
{
"term": {
"secondLevels.thirdLevels.user": "user#domain.com"
}
}
]
}
},
"inner_hits": {
"size": 100
}
}
}
]
}
}
}

How to combine multiple bool queries in elasticsearch

I want to create the equivalent of the following query -
(city = 'New York' AND state = 'NY') AND ((businessName='Java' and businessName='Shop') OR (category='Java' and category = 'Shop'))
I tried different combinations of bool queries using must and should but nothing seems to be working. Can this be done?
How about something like this:
{
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"term": {
"city": "New york"
}
},
{
"term": {
"state": "NY"
}
},
{
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"businessName": "Java"
}
},
{
"term": {
"businessName": "Shop"
}
}
]
}
},
{
"bool": {
"must": [
{
"term": {
"category": "Java"
}
},
{
"term": {
"category": "Shop"
}
}
]
}
}
]
}
}
]
}
}
}

Resources