在 Elasticsearch 中,实现多字段查询的常见方式有以下几种,每种方式适用于不同的场景:
---
### 1. **`multi_match` 查询**
- **用途**:在多个字段中执行同一查询,支持多种匹配策略。
- **关键参数**:
- `type`:指定匹配策略(如 `best_fields`, `most_fields`, `cross_fields`, `phrase`, `phrase_prefix`)。
- `fields`:指定查询的字段列表(支持通配符,如 `title^3` 表示字段权重提升)。
- **示例**:
```json
GET /_search
{
"query": {
"multi_match": {
"query": "elasticsearch",
"fields": ["title", "content^2", "tags"],
"type": "best_fields"
}
}
}
```
---
### 2. **`bool` 查询组合多个子句**
- **用途**:通过 `bool` 查询的 `should`, `must`, `filter` 等子句组合多个字段的条件。
- **场景**:需要更复杂的逻辑(如部分字段必须匹配,部分字段可选匹配)。
- **示例**:
```json
GET /_search
{
"query": {
"bool": {
"should": [
{ "match": { "title": "elasticsearch" } },
{ "match": { "description": "elasticsearch" } }
],
"minimum_should_match": 1
}
}
}
```
---
### 3. **`cross_fields` 类型**
- **用途**:将查询词拆分后,分散到多个字段中匹配(如处理姓名分散在 `first_name` 和 `last_name` 的场景)。
- **特点**:通过 `operator` 和 `analyzer` 统一控制字段行为。
- **示例**:
```json
GET /_search
{
"query": {
"multi_match": {
"query": "John Smith",
"fields": ["first_name", "last_name"],
"type": "cross_fields",
"operator": "and"
}
}
}
```
---
### 4. **`query_string` 或 `simple_query_string`**
- **用途**:使用 Lucene 语法直接指定多字段查询,适合熟悉搜索语法的用户。
- **示例**:
```json
GET /_search
{
"query": {
"query_string": {
"query": "(title:elasticsearch) OR (content:search)",
"default_field": "content"
}
}
}
```
---
### 5. **`copy_to` 字段合并**
- **用途**:通过 `copy_to` 将多个字段值复制到一个新字段,简化单字段查询。
- **步骤**:
1. 定义映射时指定 `copy_to`:
```json
"mappings": {
"properties": {
"title": { "type": "text", "copy_to": "full_text" },
"content": { "type": "text", "copy_to": "full_text" }
}
}
```
2. 查询合并后的字段:
```json
GET /_search
{
"query": {
"match": { "full_text": "elasticsearch" }
}
}
```
---
### 6. **`dis_max` 查询**
- **用途**:在多个查询中取最佳匹配的评分,忽略其他字段的评分(避免评分累加)。
- **示例**:
```json
GET /_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "elasticsearch" } },
{ "match": { "content": "elasticsearch" } }
],
"tie_breaker": 0.3
}
}
}
```
---
### 7. **`nested` 查询**
- **用途**:针对嵌套对象(nested type)中的多个字段进行联合查询。
- **示例**:
```json
GET /_search
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{ "match": { "comments.author": "John" } },
{ "match": { "comments.text": "elasticsearch" } }
]
}
}
}
}
}
```
---
### **总结**
| 方法 | 适用场景 |
|---------------------|----------------------------------|
| `multi_match` | 快速实现多字段查询,支持多种匹配策略。 |
| `bool` + `should` | 需要复杂逻辑组合时使用。 |
| `cross_fields` | 字段间内容互补(如姓名、地址拆分存储)。 |
| `copy_to` | 预定义合并字段,简化后续查询。 |
| `dis_max` | 避免低相关性字段拉低总体评分。 |
| `nested` | 嵌套对象内的多字段联合查询。 |
根据数据结构和查询需求(如是否需要字段权重、是否处理嵌套对象等),选择最合适的方式。
在 Elasticsearch 8.17 版本中,支持的多字段查询方式非常丰富,涵盖了从简单到复杂的多种场景。以下是 Elasticsearch 8.17 版本中支持的主要多字段查询方式及其特点:
---
### 1. **`multi_match` 查询**
- **用途**:在多个字段中执行同一查询,支持多种匹配策略。
- **关键参数**:
- `type`:指定匹配策略(如 `best_fields`, `most_fields`, `cross_fields`, `phrase`, `phrase_prefix`)。
- `fields`:指定查询的字段列表(支持通配符,如 `title^3` 表示字段权重提升)。
- **示例**:
```json
GET /_search
{
"query": {
"multi_match": {
"query": "elasticsearch",
"fields": ["title", "content^2", "tags"],
"type": "best_fields"
}
}
}
```
---
### 2. **`bool` 查询组合多个子句**
- **用途**:通过 `bool` 查询的 `should`, `must`, `filter` 等子句组合多个字段的条件。
- **场景**:需要更复杂的逻辑(如部分字段必须匹配,部分字段可选匹配)。
- **示例**:
```json
GET /_search
{
"query": {
"bool": {
"should": [
{ "match": { "title": "elasticsearch" } },
{ "match": { "description": "elasticsearch" } }
],
"minimum_should_match": 1
}
}
}
```
---
### 3. **`cross_fields` 类型**
- **用途**:将查询词拆分后,分散到多个字段中匹配(如处理姓名分散在 `first_name` 和 `last_name` 的场景)。
- **特点**:通过 `operator` 和 `analyzer` 统一控制字段行为。
- **示例**:
```json
GET /_search
{
"query": {
"multi_match": {
"query": "John Smith",
"fields": ["first_name", "last_name"],
"type": "cross_fields",
"operator": "and"
}
}
}
```
---
### 4. **`query_string` 或 `simple_query_string`**
- **用途**:使用 Lucene 语法直接指定多字段查询,适合熟悉搜索语法的用户。
- **示例**:
```json
GET /_search
{
"query": {
"query_string": {
"query": "(title:elasticsearch) OR (content:search)",
"default_field": "content"
}
}
}
```
---
### 5. **`copy_to` 字段合并**
- **用途**:通过 `copy_to` 将多个字段值复制到一个新字段,简化单字段查询。
- **步骤**:
1. 定义映射时指定 `copy_to`:
```json
"mappings": {
"properties": {
"title": { "type": "text", "copy_to": "full_text" },
"content": { "type": "text", "copy_to": "full_text" }
}
}
```
2. 查询合并后的字段:
```json
GET /_search
{
"query": {
"match": { "full_text": "elasticsearch" }
}
}
```
---
### 6. **`dis_max` 查询**
- **用途**:在多个查询中取最佳匹配的评分,忽略其他字段的评分(避免评分累加)。
- **示例**:
```json
GET /_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "elasticsearch" } },
{ "match": { "content": "elasticsearch" } }
],
"tie_breaker": 0.3
}
}
}
```
---
### 7. **`nested` 查询**
- **用途**:针对嵌套对象(nested type)中的多个字段进行联合查询。
- **示例**:
```json
GET /_search
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{ "match": { "comments.author": "John" } },
{ "match": { "comments.text": "elasticsearch" } }
]
}
}
}
}
}
```
---
### 8. **`combined_fields` 查询(Elasticsearch 7.11+)**
- **用途**:在多个字段中联合搜索一个完整的短语或关键词,支持字段权重和统一的文本分析。
- **示例**:
```json
GET /_search
{
"query": {
"combined_fields": {
"query": "distributed search engine",
"fields": ["title", "content", "description"],
"operator": "and"
}
}
}
```
---
### 9. **`span_near` 和 `span_multi` 查询**
- **用途**:用于复杂的跨度查询(span queries),支持多字段的邻近匹配。
- **示例**:
```json
GET /_search
{
"query": {
"span_near": {
"clauses": [
{ "span_term": { "title": "elasticsearch" } },
{ "span_term": { "content": "search" } }
],
"slop": 5,
"in_order": false
}
}
}
```
---
### 10. **`script_score` 查询**
- **用途**:通过脚本自定义评分逻辑,支持多字段联合评分。
- **示例**:
```json
GET /_search
{
"query": {
"script_score": {
"query": {
"bool": {
"should": [
{ "match": { "title": "elasticsearch" } },
{ "match": { "content": "elasticsearch" } }
]
}
},
"script": {
"source": "doc['title'].value.length() + doc['content'].value.length()"
}
}
}
}
```
---
### **总结**
| 方法 | 适用场景 |
|---------------------|----------------------------------|
| `multi_match` | 快速实现多字段查询,支持多种匹配策略。 |
| `bool` + `should` | 需要复杂逻辑组合时使用。 |
| `cross_fields` | 字段间内容互补(如姓名、地址拆分存储)。 |
| `copy_to` | 预定义合并字段,简化后续查询。 |
| `dis_max` | 避免低相关性字段拉低总体评分。 |
| `nested` | 嵌套对象内的多字段联合查询。 |
| `combined_fields` | 多字段联合搜索短语,支持统一分析器。 |
| `span_near` | 复杂的邻近匹配查询。 |
| `script_score` | 自定义评分逻辑,支持多字段联合评分。 |
根据数据结构和查询需求(如是否需要字段权重、是否处理嵌套对象等),选择最合适的方式。