Elasticsearch how to use multi_match with wildcard

ElasticsearchWildcard

Elasticsearch Problem Overview


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

Elasticsearch Solutions


Solution 1 - Elasticsearch

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

Solution 2 - Elasticsearch

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.

Solution 3 - Elasticsearch

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

Solution 4 - Elasticsearch

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.

Solution 5 - Elasticsearch

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

Solution 6 - Elasticsearch

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',
              },
            },
          ],

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartin Kvasňa KvasnicaView Question on Stackoverflow
Solution 1 - ElasticsearchramseykhalafView Answer on Stackoverflow
Solution 2 - ElasticsearchCatherine TsokurView Answer on Stackoverflow
Solution 3 - ElasticsearchDavid JohnsonView Answer on Stackoverflow
Solution 4 - ElasticsearchramseykhalafView Answer on Stackoverflow
Solution 5 - Elasticsearchuser11913024View Answer on Stackoverflow
Solution 6 - ElasticsearchRafiqView Answer on Stackoverflow