0

I'm using ES 7.14/Kibana 7.10, I have to search for adjacent words (any order), hence I'm using this query:

{
 "query":{
    "bool":{
        "must":[
            {
                "query_string":{
                    "query":"*antonio* *banderas*",
                    "fields":[
                        "text"
                    ],
                    "default_operator":"and",
                }
            }]
      }
  }
}

This works ok for a text plain field. Now, I have a nested field metadata, let's say the mapping is

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

and I would like to search that nested field in the same way (adjacent words search), so assumed that it's is possibile to write a nested query for query_string in this way

{
  "query": {
    "query_string": {
      "query": "metadata.text:*antonio* *banderas*"
    }
  }
}

How to adapt this approach to the previous one with default_operator=and etc.? If I do

   {
      "query": {
        "query_string": {
          "query": "metadata.text:*antonio* *banderas*",
          "default_operator": "and"
        }
      }
    }

I don't get any result (but any error too).

A similar question, but related to matching adjacent words for multiple nested fields is here.

loretoparisi
  • 15,724
  • 11
  • 102
  • 146
  • for nested field you need to use nested query , with normal queries it will be treated as flat text ie these will not be treated as separate documents – jaspreet chahal Aug 23 '21 at 15:55

1 Answers1

1

Adjacent word with any order should not be search with query_string but wildcard or match or term or span_term

There is also a mapping type wildcard optimised for this usage, depends on what type of queries you will need.

So for you first example :

{
  "query": {
    "bool": {
      "must": [
        {
          "wildcard": {
            "text": "*antonio*"
          }
        },
        {
          "wildcard": {
            "text": "*banderas*"
          }
        }
      ]
    }
  }
}

OR

{
  "query": {
    "bool": {
      "must": [
        {
          "wildcard": {
            "text": "*antonio*banderas*"
          }
        }
      ]
    }
  }
}

and for nested queries :

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "metadata",
            "query": {
              "bool": {
                "must": [
                  {
                    "wildcard": {
                      "metadata.text": "*antonio*"
                    }
                  },
                  {
                    "wildcard": {
                      "metadata.text": "*banderas*"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
ExploZe
  • 426
  • 4
  • 9
  • Thank you. Since my search field type is `text` can I apply a `wildcard` query? If not, could you provide an alternative example for `term` or `match`? – loretoparisi Aug 29 '21 at 17:29
  • 1
    Yes you can use wildcard on `text` field, just remember that `text` field type split phrase in tokens so it's like having a bunch of terms and not a phrase, to see this in action, use POST /myindice/_analyse `{"text": "my phrase is cool"}` to see how it works under the hood – ExploZe Aug 29 '21 at 21:15
  • Thank you. Just a note, but significative. For some reason I ignore, it only works with `match` field and `query_string`, where the former (`match`) it's 8x the latter (!); `wildcard` and `terms` do not return any result if used in this way https://gist.github.com/loretoparisi/7383a912686c56428849efe4e553758a – loretoparisi Aug 30 '21 at 13:38
  • Yes obviously, like I said `text` type transform your text into a bunch of tokens, so match will try to match one of the token, so for example `my phrase` become tokens `my` and `phrase` and you cannot `match` with `my*phrase` since it's no in valid with the `my` token and either with `phrase` token – ExploZe Aug 30 '21 at 14:28
  • I have an extension of this question related matching adjacent words, but for multiple nested fields - https://stackoverflow.com/questions/69107109/elasticsearch-adjacent-words-for-nested-queries-over-multiple-nested-fields – loretoparisi Sep 08 '21 at 17:03