【Elasticsearch】multi_match查询
`multi_match`是 Elasticsearch 中一种非常强大的查询类型,允许你在多个字段中灵活地执行文本搜索。它基于`match`查询扩展而来,提供了多种方式来处理多字段查询,以满足不同的搜索需求。以下是对`multi_match`查询的详细描述,包括它的主要特性、类型、参数以及使用场景。
---
1.`multi_match`的基本概念
`multi_match`查询允许你在多个字段中搜索同一个查询字符串。它会根据指定的字段列表和查询类型(`type`),将查询字符串分析为单个词项,然后在这些字段中查找匹配的文档。
基本语法
```json
{
"query": {
"multi_match": {
"query": "search text",
"fields": ["field1", "field2", "field3"],
"type": "query_type", // 如 best_fields, most_fields, cross_fields 等
"operator": "AND/OR",
"minimum_should_match": "number_or_percentage",
"boost": 1.0,
"analyzer": "standard",
"fuzziness": "AUTO",
"prefix_length": 0,
"max_expansions": 50,
"lenient": false,
"zero_terms_query": "none/all",
"auto_generate_synonyms_phrase_query": true,
"fuzzy_transpositions": true,
"tie_breaker": 0.0
}
}
}
```
2.`multi_match`的主要参数
`query`
• 描述:查询字符串,即用户输入的搜索内容。
• 示例:`"query": "Will Smith"`。
`fields`
• 描述:指定要搜索的字段列表。可以使用通配符(如`*`)匹配多个字段。
• 示例:
```json
"fields": ["first_name", "last_name", "full_name"]
```
或者:
```json
"fields": ["title", "content", "comments.*"]
```
`type`
• 描述:指定`multi_match`查询的类型,决定了查询词项如何在多个字段中匹配。常见的类型包括:
• `best_fields`(默认):在所有字段中独立匹配查询词项,选择分数最高的字段作为匹配结果。
• `most_fields`:在所有字段中独立匹配查询词项,将所有字段的分数相加。
• `cross_fields`:将多个字段视为一个整体,查询词项可以在任意字段中匹配。
• `phrase`:在每个字段中执行短语匹配。
• `phrase_prefix`:在每个字段中执行短语前缀匹配。
• `bool_prefix`:在每个字段中执行布尔前缀匹配。
`operator`
• 描述:指定查询词项之间的逻辑关系,可选值为`AND`或`OR`。
• 默认值:`OR`。
• 示例:
```json
"operator": "AND"
```
`minimum_should_match`
• 描述:指定查询词项中至少需要匹配的数量,可以是一个绝对值或百分比。
• 示例:
```json
"minimum_should_match": "50%"
```
`boost`
• 描述:为查询结果的分数(`_score`)设置一个乘数,用于调整匹配文档的相关性。
• 默认值:`1.0`。
• 示例:
```json
"boost": 2.0
```
`analyzer`
• 描述:指定查询时使用的分析器。如果字段使用了不同的分析器,可以通过显式指定`analyzer`参数,将所有字段统一使用同一个分析器进行查询。
• 示例:
```json
"analyzer": "standard"
```
`fuzziness`
• 描述:允许查询词项有一定的拼写错误容忍度。可选值包括`0`、`1`、`2`或`AUTO`。
• 默认值:`0`(不启用模糊匹配)。
• 示例:
```json
"fuzziness": "AUTO"
```
`prefix_length`
• 描述:在模糊匹配中,指定前缀的长度,这部分不会被模糊化。
• 默认值:`0`。
• 示例:
```json
"prefix_length": 2
```
`max_expansions`
• 描述:在模糊匹配中,指定最多扩展的词项数量。
• 默认值:`50`。
• 示例:
```json
"max_expansions": 10
```
`lenient`
• 描述:当设置为`true`时,允许查询忽略字段中的格式错误(如日期格式错误)。
• 默认值:`false`。
• 示例:
```json
"lenient": true
```
`zero_terms_query`
• 描述:指定当查询字符串为空时的行为。可选值为`none`(不返回任何结果)或`all`(返回所有文档)。
• 默认值:`none`。
• 示例:
```json
"zero_terms_query": "none"
```
`auto_generate_synonyms_phrase_query`
• 描述:是否自动生成同义词短语查询。
• 默认值:`true`。
• 示例:
```json
"auto_generate_synonyms_phrase_query": true
```
`fuzzy_transpositions`
• 描述:是否允许模糊匹配中的字符交换(如`ab`匹配`ba`)。
• 默认值:`true`。
• 示例:
```json
"fuzzy_transpositions": true
```
`tie_breaker`
• 描述:在`best_fields`类型中,用于调整多个字段匹配时的分数权重。
• 默认值:`0.0`。
• 示例:
```json
"tie_breaker": 0.3
```
---
3.`multi_match`的主要类型
3.1`best_fields`(默认)
• 特点:
• 查询词项会在每个字段中独立匹配。
• 选择分数最高的字段作为匹配结果。
• 适用于查询词项在单个字段中最佳匹配的场景。
• 示例:
```json
{
"query": {
"multi_match": {
"query": "quick brown fox",
"fields": ["title", "description"],
"type": "best_fields"
}
}
}
```
3.2`most_fields`
• 特点:
• 查询词项会在每个字段中独立匹配。
• 将所有字段的分数相加。
• 适用于查询词项在多个字段中分别匹配的场景。
• 示例:
```json
{
"query": {
"multi_match": {
"query": "quick brown fox",
"fields": ["title", "description"],
"type": "most_fields"
}
}
}
```
3.3`cross_fields`
• 特点:
• 将多个字段视为一个整体,查询词项可以在任意字段中匹配。
• 适用于查询词项分布在多个字段中的场景。
• 需要所有字段使用相同的分析器。
• 示例:
```json
{
"query": {
"multi_match": {
"query": "Will Smith",
"fields": ["first_name", "last_name"],
"type": "cross_fields"
}
}
}
```
3.4`phrase`
• 特点:
• 在每个字段中执行短语匹配。
• 查询词项必须按顺序出现在字段中。
• 示例:
```json
{
"query": {
"multi_match": {
"query": "quick brown fox",
"fields": ["title", "description"],
"type": "phrase"
}
}
}
```
3.5`phrase_prefix`
• 特点:
• 在每个字段中执行短语前缀匹配。
• 查询词项的前缀必须按顺序出现在字段中。
• 示例:
```json
{
"query": {
"multi_match": {
"query": "quick bro",
"fields": ["title", "description"],
"type": "phrase_prefix"
}
}
}
```
3.6`bool_prefix`
• 特点:
• 在每个字段中执行布尔
3.6`bool_prefix`
• 特点:
• 在每个字段中执行布尔前缀匹配。它结合了布尔查询(`bool`)和前缀匹配(`prefix`)的功能。
• 适用于需要在多个字段中匹配前缀的场景,同时支持布尔逻辑(如`AND`、`OR`)。
• 示例:
```json
{
"query": {
"multi_match": {
"query": "quick bro",
"fields": ["title", "description"],
"type": "bool_prefix"
}
}
}
```
• 这个查询会在`title`和`description`字段中查找以`"quick bro"`开头的内容,支持布尔逻辑组合。
---
4.使用场景和示例
4.1 搜索用户信息
假设有一个用户信息索引,包含`first_name`和`last_name`字段,需要搜索用户`Will Smith`。
• 字段中心(`best_fields`或`most_fields`):
```json
{
"query": {
"multi_match": {
"query": "Will Smith",
"fields": ["first_name", "last_name"],
"type": "best_fields",
"operator": "AND"
}
}
}
```
• 匹配逻辑:`Will`和`Smith`都必须出现在`first_name`或`last_name`中,选择分数最高的字段作为匹配结果。
• 词项中心(`cross_fields`):
```json
{
"query": {
"multi_match": {
"query": "Will Smith",
"fields": ["first_name", "last_name"],
"type": "cross_fields",
"operator": "AND"
}
}
}
```
• 匹配逻辑:`Will`和`Smith`可以分别出现在`first_name`和`last_name`中。
4.2 搜索文章内容
假设有一个文章索引,包含`title`和`content`字段,需要搜索包含`"Elasticsearch"`和`"search"`的文章。
• 字段中心(`most_fields`):
```json
{
"query": {
"multi_match": {
"query": "Elasticsearch search",
"fields": ["title", "content"],
"type": "most_fields",
"operator": "AND"
}
}
}
```
• 匹配逻辑:`Elasticsearch`和`search`都必须出现在`title`或`content`中,将两个字段的分数相加。
• 词项中心(`cross_fields`):
```json
{
"query": {
"multi_match": {
"query": "Elasticsearch search",
"fields": ["title", "content"],
"type": "cross_fields",
"operator": "AND"
}
}
}
```
• 匹配逻辑:`Elasticsearch`和`search`可以分别出现在`title`和`content`中。
4.3 搜索评论内容
假设有一个评论索引,包含`author`和`comment`字段,需要搜索包含`"John"`或`"comment"`的评论。
• 字段中心(`best_fields`):
```json
{
"query": {
"multi_match": {
"query": "John comment",
"fields": ["author", "comment"],
"type": "best_fields",
"operator": "OR"
}
}
}
```
• 匹配逻辑:`John`或`comment`出现在`author`或`comment`中,选择分数最高的字段作为匹配结果。
• 词项中心(`cross_fields`):
```json
{
"query": {
"multi_match": {
"query": "John comment",
"fields": ["author", "comment"],
"type": "cross_fields",
"operator": "OR"
}
}
}
```
• 匹配逻辑:`John`或`comment`可以分别出现在`author`和`comment`中。
---
5.参数详解
5.1`operator`
• `AND`:所有查询词项都必须匹配。
• 示例:`"operator": "AND"`
• `OR`:任意一个查询词项匹配即可(默认值)。
• 示例:`"operator": "OR"`
5.2`minimum_should_match`
• 作用:指定至少需要匹配的查询词项数量。
• 示例:
• 绝对值:`"minimum_should_match": 2`
• 百分比:`"minimum_should_match": "50%"`
5.3`fuzziness`
• 作用:允许查询词项有一定的拼写错误容忍度。
• 示例:
• `"fuzziness": "AUTO"`:自动调整模糊匹配的容忍度。
• `"fuzziness": 1`:允许一个字符的拼写错误。
5.4`analyzer`
• 作用:指定查询时使用的分析器。
• 示例:
• `"analyzer": "standard"`:使用标准分析器。
5.5`boost`
• 作用:为查询结果的分数设置一个乘数。
• 示例:
• `"boost": 2.0`:将匹配文档的分数乘以 2。
5.6`tie_breaker`
• 作用:在`best_fields`类型中,用于调整多个字段匹配时的分数权重。
• 示例:
• `"tie_breaker": 0.3`:将次要字段的分数乘以 0.3 后加到主要字段的分数上。
---
6.性能和优化
6.1 字段数量限制
• 默认情况下,`multi_match`查询的子句数量受到`indices.query.bool.max_clause_count`的限制,默认值为 4096。
• 如果字段过多或查询词项过多,可能会超出这个限制,导致查询失败。
6.2 分析器一致性
• 对于`cross_fields`类型,所有字段必须使用相同的分析器,否则可能会导致字段被分组,影响查询结果。
6.3 使用`minimum_should_match`
• 合理设置`minimum_should_match`参数可以减少匹配过多无关文档的问题,提高查询的精确度。
---
7.总结
`multi_match`查询是 Elasticsearch 中非常灵活和强大的查询类型,适用于多种多字段搜索场景。通过选择合适的查询类型(如`best_fields`、`most_fields`、`cross_fields`等)和调整参数(如`operator`、`minimum_should_match`、`fuzziness`等),可以实现灵活的搜索逻辑,满足不同的业务需求。
• 字段中心(Field-Centric):适合字段内容差异较大,或者字段具有不同分析器的场景。
• 词项中心(Term-Centric):适合查询词项分布在多个字段中的场景,需要跨字段组合匹配。
根据你的具体需求选择合适的查询类型和参数,可以实现更高效的查询效果。