75

I have a User object with properties Name and Surname. I want to search these fields using one query, and I found multi_match in the documentation, but I don't know how to properly use that with a wildcard. Is it possible?

I tried with a multi_match query but it didn't work:

{
    "query": {
        "multi_match": {
            "query": "*mar*",
            "fields": [
                "user.name",
                "user.surname"
            ]
        }
    }
}
Michael Mior
  • 28,107
  • 9
  • 89
  • 113

6 Answers6

113

Alternatively you could use a query_string query with wildcards.

"query": {
    "query_string": {
        "query": "*mar*",
        "fields": ["user.name", "user.surname"]
    }
}

This will be slower than using an nGram filter at index-time (see my other answer), but if you are looking for a quick and dirty solution...

Also I am not sure about your mapping, but if you are using user.name instead of name your mapping needs to look like this:

"your_type_name_here": {
    "properties": {
        "user": {
            "type": "object",
            "properties": {
                "name": {
                    "type": "string"
                },
                "surname": {
                    "type": "string"
                }
            }
        }
    }
}
ramseykhalaf
  • 3,371
  • 2
  • 17
  • 16
  • 1
    The query_string does more than that, it exposes the lucene query syntax. I would rather look at the wildcard query. – javanna Jun 05 '13 at 20:53
  • Can you paste a link to details of what `query_string` does? I'm a little confused about the behaviour... – ramseykhalaf Jun 09 '13 at 07:18
  • 1
    Look at the bottom of this page for a comparison between query_string and match query: http://www.elasticsearch.org/guide/reference/query-dsl/match-query/ – javanna Jun 10 '13 at 08:42
  • 5
    The answer is not answering the question how to use multi_match and wildcard. Does someone has an idea? – Gizzmo May 14 '14 at 13:45
  • elastics docs about multimatch and regexp are such a headache. this worked great, thanks. – caro Sep 21 '17 at 14:49
20

Such a query worked for me:

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "bool": {
          "should": [
            {"query": {"wildcard": {"user.name": {"value": "*mar*"}}}},
            {"query": {"wildcard": {"user.surname": {"value": "*mar*"}}}}
          ]
        }
      }
    }
  }
}

Similar to what you are doing, except that in my case there could be different masks for different fields.

  • Thanks catherine Tsokur. I am also trying the same way but is there a way i can keep multiple wildcard conditions of same column. example : user.name can be of 5 different wildcard patterns. Please suggest how can i use that condition . – Sajal Saxena Jul 08 '20 at 12:57
12

I just did this now:

GET _search {
    "query": {
        "bool": {
            "must": [
                {
                    "range": {
                        "theDate": {
                            "gte": "2014-01-01",
                            "lte": "2014-12-31"
                        }
                    }
                },
                {
                    "match" : {
                        "Country": "USA"
                    }
                }
            ],
            "should": [
                {
                    "wildcard" : { "Id_A" : "0*" }
                },
                {
                    "wildcard" : { "Id_B" : "0*" }
                }
            ],"minimum_number_should_match": 1
        }
    }
}
OhBeWise
  • 5,350
  • 3
  • 32
  • 60
David Johnson
  • 121
  • 1
  • 2
8

Similar to suggestion above, but this is simple and worked for me:

{
"query": {
    "bool": {
        "must":
        [
            {
                "wildcard" : { "processname.keyword" : "*system*" }
            },
            {
                "wildcard" : { "username" : "*admin*" }
            },
            {
                "wildcard" : { "device_name" : "*10*" }
            }
        ]
    }
}
}
7

I would not use wildcards, it will not scale well. You are asking a lot of the search engine at query time. You can use the nGram filter, to do the processing at index-time not search time.

See this discussion on the nGram filter.

After indexing the name and surname correctly (change your mapping, there are examples in the above link) you can use multi-match but without wildcards and get the expected results.

Community
  • 1
  • 1
ramseykhalaf
  • 3,371
  • 2
  • 17
  • 16
1
description: {
  type: 'keyword',
  normalizer: 'useLowercase',
},
product: {
      type: 'object',
      properties: {
        name: {
          type: 'keyword',
          normalizer: 'useLowercase',
        },
      },
    },
activity: {
      type: 'object',
      properties: {
        name: {
          type: 'keyword',
          normalizer: 'useLowercase',
        },
      },
    },

query:

          query: {
            bool: {
              must: [
                {
                  bool: {
                    should: [
                      {
                        wildcard: {
                          description: {
                            value: `*${value ? value : ''}*`,
                            boost: 1.0,
                            rewrite: 'constant_score',
                          },
                        },
                      },
                      {
                        wildcard: {
                          'product.name': {
                            value: `*${value ? value : ''}*`,
                            boost: 1.0,
                            rewrite: 'constant_score',
                          },
                        },
                      },
                      {
                        wildcard: {
                          'activity.name': {
                            value: `*${value ? value : ''}*`,
                            boost: 1.0,
                            rewrite: 'constant_score',
                          },
                        },
                      },
                    ],
                  },
                },
                {
                  match: {
                    recordStatus: RecordStatus.Active,
                  },
                },
                {
                  bool: {
                    must_not: [
                      {
                        term: {
                          'user.id': req.currentUser?.id,
                        },
                      },
                    ],
                  },
                },
                {
                  bool: {
                    should: tags
                      ? tags.map((name: string) => {
                          return {
                            nested: {
                              path: 'tags',
                              query: {
                                match: {
                                  'tags.name': name,
                                },
                              },
                            },
                          };
                        })
                      : [],
                  },
                },
              ],
              filter: {
                bool: {
                  must_not: {
                    terms: {
                      id: existingIds ? existingIds : [],
                    },
                  },
                },
              },
            },
          },
          sort: [
            {
              updatedAt: {
                order: 'desc',
              },
            },
          ],
Rafiq
  • 8,987
  • 4
  • 35
  • 35