背景 在搜索引擎和数据存储中,高效处理多样化的查询需求至关重要。以公司名称和时间字段为例,这些字段可能需要同时支持全文搜索和精确匹配。Elasticsearch 提供了多字段功能,允许单个字段展示多种行为,例如分词搜索和精确匹配。本文将分析如何利用多字段功能,处理具有多种类型需求的字段,如 name 和时间字段。 多字段基础 在 Elasticsearch 中,一个字段无法具备多种类型,但通过 多字段机制 (Multi-fields),同一个字段可以有多种功能,如全文搜索和精确匹配。 尽管一个字段只能有一个主类型,但通过属性 fields,可以为字段增加子字段,每个子字段可以有自己的类型和属性。 基本示例 下面是一个多字段的配置:
{ "mappings": { "properties": { "name": { "type": "text", // 主字段,用于全文搜索 "fields": { "keyword": { // 子字段名 "type": "keyword", // 子字段,用于精确匹配 "ignore_above": 256 } } } } } }
name 字段应用场景 想象一个情况:在一个全球化的应用中,需要搜索公司名称,比如“Dragon Ball Co., Ltd.”: 需求分析 1. 支持全文搜索: ◦ 用户不许能输入全部名称,但输入“Dragon” 或 “Ball”,应该返回有关的文档。 2. 支持精确匹配: ◦ 实际中需要精确匹配全名“Dragon Ball Co., Ltd.”,应该使用未分词的原始值进行匹配。 选择使用多字段
- 全文搜索: 采用主字段
name
(类型为text
),支持分词后搜索:
GET dev_companies/_search { "query": { "match": { "name": "Dragon Ball" } } }
- 精确匹配: 采用子字段
name.keyword
(类型为keyword
),用于匹配未分词的值:
GET dev_companies/_search { "query": { "term": { "name.keyword": "Dragon Ball Co., Ltd." } } }
- 短语应匹配: 如果需要匹配分词序列,使用
match_phrase
及远离参数slop
:
GET dev_companies/_search
{
"query": {
"match_phrase": {
"name": {
"query": "Dragon Ball",
"slop": 2
}
}
}
}