在 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` ? ? ?| 自定義評分邏輯,支持多字段聯合評分。 ? ? |
根據數據結構和查詢需求(如是否需要字段權重、是否處理嵌套對象等),選擇最合適的方式。