I have a 3 level nested object something like below, I want to index these objects in elastic search. Requirement here is users will write a search query keywords like "keyword1 keyword2 ..." and I want to return objects that has all of these keywords in it (at any level i.e. AND operation).
[
{
"country":[
{
"name":"India",
"ext_code":"91",
"states":[
{
"name":"Karnataka",
"ext_code":"04",
"cities":[
{
"name":"Bangalore",
"ext_code":"080"
}
]
}
]
}
]
}
]
Currently, I store them in nested format using the following mapping:
{
"mappings":{
"doc":{
"properties":{
"name": {"type":"text"},
"ext_code": {"type":"text"}
"state" {
"type": "nested",
"properties": {
"name": {"type":"text"},
"ext_code": {"type":"text"}
"city" {
"type": "nested",
"properties": {
"name": {"type":"text"}
"ext_code": {"type":"text"}
}
}
}
}
}
}
}
}
And while searching, I pass elastic search a nested query to search on all levels like below:
{
"query": {
"bool": {
"should": [
{
"multi_match": {
"query": "keyword1 keyword2 ...",
"fields": ['name']
}
},
{
"nested": {
"path": 'state',
"query": {
"multi_match": {
"query": "keyword1 keyword2 ...",
"fields": ['state.name']
}
}
}
},
{
"nested": {
"path": 'state.city',
"query": {
"multi_match": {
"query": "keyword1 keyword2 ...",
"fields": ['state.city.name']
}
}
}
}
]
}
}
}
When sending multiple tokens to search, it applies an OR operation returning documents containing any of the search tokens.
Is there a way to configure Elastic Search to perform an AND operation for multiple tokens in search query?
One solution would be to index all the values of the name
fields inside a custom all
field. First define your index and mappings like this:
PUT index
{
"mappings": {
"doc": {
"properties": {
"all": { <-- all field that will contain all values
"type": "text"
},
"name": {
"type": "text",
"copy_to": "all" <-- copy value to all field
},
"ext_code": {
"type": "text"
},
"state": {
"type": "nested",
"properties": {
"name": {
"type": "text",
"copy_to": "all" <-- copy value to all field
},
"ext_code": {
"type": "text"
},
"city": {
"type": "nested",
"properties": {
"name": {
"type": "text",
"copy_to": "all" <-- copy value to all field
},
"ext_code": {
"type": "text"
}
}
}
}
}
}
}
}
}
Then index your documents:
POST index/doc
{
"name": "India",
"ext_code": "91",
"state": [
{
"name": "Karnataka",
"ext_code": "04",
"city": [
{
"name": "Bangalore",
"ext_code": "080"
}
]
}
]
}
Finally, using a simple match query, you can search for any value anywhere in the document:
POST index/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"all": {
"query": "bangalore india",
"operator": "and"
}
}
}
]
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With