Home > database >  ElasticSearch adjacent words for nested queries over multiple nested fields
ElasticSearch adjacent words for nested queries over multiple nested fields

Time:09-17

To search for adjacent words for nested (or not) queries, the solution is the following (see here for the answer):

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "metadata",
            "query": {
              "bool": {
                "must": [
                  {
                    "wildcard": {
                      "metadata.text": "*antonio*"
                    }
                  },
                  {
                    "wildcard": {
                      "metadata.text": "*banderas*"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

This works OK. But, supposed to have multiple nested fields in which search *antonio* *banderas* in the same way, let's say now we have this mapping:

{
    "mappings:": {
        "properties": {
            "text": {
                "type": "text"
            },
            "metadata": {
                "type": "nested",
                "properties": {
                    "text": {
                        "type": "text"
                    }
                }
            },
            "other_metadata": {
                "type": "nested",
                "properties": {
                    "text": {
                        "type": "text"
                    }
                }
            }
        }
    }
}

If I want to search the adjacent words in both nested fields metadata and other_metadata shall I use match or should? I want to have a result that matches at least one of the patterns metadata or other_metadata, so I thought to use should and set minimum_should_match to the number of tokens of the query (separated by a \s - space char) in this way:

{
    "should": [{
            "nested": {
                "path": "metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "metadata.text": "*antonio*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        },
        {
            "nested": {
                "path": "metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "metadata.text": "*banderas*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        },
        {
            "nested": {
                "path": "other_metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "other_metadata.text": "*antonio*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        },
        {
            "nested": {
                "path": "other_metadata",
                "query": {
                    "bool": {
                        "must": {
                            "wildcard": {
                                "other_metadata.text": "*banderas*"
                            }
                        }
                    }
                },
                "ignore_unmapped": true
            }
        }
    ],
    "minimum_should_match": 2
}

This seems to work, but my doubt is the following: the minimum_should_match=2 condition here will assure that at least two ones of those four conditions match, but not that those two matching conditions are both related to the same pattern (like metadata for both words *antonio* and *banderas*. If so, how to ensure that? Using must maybe? But how?

CodePudding user response:

You can do kind of sub queries like this :

bool => should => bool => filter/must/should

{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "metadata.text": "*antonio*"
                        }
                      }
                    }
                  }
                }
              },
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "metadata.text": "*banderas*"
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "other_metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "other_metadata.text": "*antonio*"
                        }
                      }
                    }
                  }
                }
              },
              {
                "nested": {
                  "ignore_unmapped": true,
                  "path": "other_metadata",
                  "query": {
                    "bool": {
                      "must": {
                        "wildcard": {
                          "other_metadata.text": "*banderas*"
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}
  • Related