- Elasticsearch 指南其他版本
- 8.17 中的新功能
- Elasticsearch 基础
- 快速入门
- 设置 Elasticsearch
- 升级 Elasticsearch
- 索引模块
- 映射
- 文本分析
- 索引模板
- 数据流
- 摄取管道
- 别名
- 搜索您的数据
- 重新排名
- 查询 DSL
- 聚合
- 地理空间分析
- 连接器
- EQL
- ES|QL
- SQL
- 脚本
- 数据管理
- 自动缩放
- 监视集群
- 汇总或转换数据
- 设置高可用性集群
- 快照和还原
- 保护 Elastic Stack 的安全
- Watcher
- 命令行工具
- elasticsearch-certgen
- elasticsearch-certutil
- elasticsearch-create-enrollment-token
- elasticsearch-croneval
- elasticsearch-keystore
- elasticsearch-node
- elasticsearch-reconfigure-node
- elasticsearch-reset-password
- elasticsearch-saml-metadata
- elasticsearch-service-tokens
- elasticsearch-setup-passwords
- elasticsearch-shard
- elasticsearch-syskeygen
- elasticsearch-users
- 优化
- 故障排除
- 修复常见的集群问题
- 诊断未分配的分片
- 向系统中添加丢失的层
- 允许 Elasticsearch 在系统中分配数据
- 允许 Elasticsearch 分配索引
- 索引将索引分配过滤器与数据层节点角色混合,以在数据层之间移动
- 没有足够的节点来分配所有分片副本
- 单个节点上索引的分片总数已超过
- 每个节点的分片总数已达到
- 故障排除损坏
- 修复磁盘空间不足的数据节点
- 修复磁盘空间不足的主节点
- 修复磁盘空间不足的其他角色节点
- 启动索引生命周期管理
- 启动快照生命周期管理
- 从快照恢复
- 故障排除损坏的存储库
- 解决重复的快照策略失败问题
- 故障排除不稳定的集群
- 故障排除发现
- 故障排除监控
- 故障排除转换
- 故障排除 Watcher
- 故障排除搜索
- 故障排除分片容量健康问题
- 故障排除不平衡的集群
- 捕获诊断信息
- REST API
- API 约定
- 通用选项
- REST API 兼容性
- 自动缩放 API
- 行为分析 API
- 紧凑和对齐文本 (CAT) API
- 集群 API
- 跨集群复制 API
- 连接器 API
- 数据流 API
- 文档 API
- 丰富 API
- EQL API
- ES|QL API
- 功能 API
- Fleet API
- 图表探索 API
- 索引 API
- 别名是否存在
- 别名
- 分析
- 分析索引磁盘使用量
- 清除缓存
- 克隆索引
- 关闭索引
- 创建索引
- 创建或更新别名
- 创建或更新组件模板
- 创建或更新索引模板
- 创建或更新索引模板(旧版)
- 删除组件模板
- 删除悬挂索引
- 删除别名
- 删除索引
- 删除索引模板
- 删除索引模板(旧版)
- 存在
- 字段使用情况统计信息
- 刷新
- 强制合并
- 获取别名
- 获取组件模板
- 获取字段映射
- 获取索引
- 获取索引设置
- 获取索引模板
- 获取索引模板(旧版)
- 获取映射
- 导入悬挂索引
- 索引恢复
- 索引段
- 索引分片存储
- 索引统计信息
- 索引模板是否存在(旧版)
- 列出悬挂索引
- 打开索引
- 刷新
- 解析索引
- 解析集群
- 翻转
- 收缩索引
- 模拟索引
- 模拟模板
- 拆分索引
- 解冻索引
- 更新索引设置
- 更新映射
- 索引生命周期管理 API
- 推理 API
- 信息 API
- 摄取 API
- 许可 API
- Logstash API
- 机器学习 API
- 机器学习异常检测 API
- 机器学习数据帧分析 API
- 机器学习训练模型 API
- 迁移 API
- 节点生命周期 API
- 查询规则 API
- 重新加载搜索分析器 API
- 存储库计量 API
- 汇总 API
- 根 API
- 脚本 API
- 搜索 API
- 搜索应用程序 API
- 可搜索快照 API
- 安全 API
- 身份验证
- 更改密码
- 清除缓存
- 清除角色缓存
- 清除权限缓存
- 清除 API 密钥缓存
- 清除服务帐户令牌缓存
- 创建 API 密钥
- 创建或更新应用程序权限
- 创建或更新角色映射
- 创建或更新角色
- 批量创建或更新角色 API
- 批量删除角色 API
- 创建或更新用户
- 创建服务帐户令牌
- 委托 PKI 身份验证
- 删除应用程序权限
- 删除角色映射
- 删除角色
- 删除服务帐户令牌
- 删除用户
- 禁用用户
- 启用用户
- 注册 Kibana
- 注册节点
- 获取 API 密钥信息
- 获取应用程序权限
- 获取内置权限
- 获取角色映射
- 获取角色
- 查询角色
- 获取服务帐户
- 获取服务帐户凭据
- 获取安全设置
- 获取令牌
- 获取用户权限
- 获取用户
- 授予 API 密钥
- 具有权限
- 使 API 密钥失效
- 使令牌失效
- OpenID Connect 准备身份验证
- OpenID Connect 身份验证
- OpenID Connect 注销
- 查询 API 密钥信息
- 查询用户
- 更新 API 密钥
- 更新安全设置
- 批量更新 API 密钥
- SAML 准备身份验证
- SAML 身份验证
- SAML 注销
- SAML 失效
- SAML 完成注销
- SAML 服务提供商元数据
- SSL 证书
- 激活用户配置文件
- 禁用用户配置文件
- 启用用户配置文件
- 获取用户配置文件
- 建议用户配置文件
- 更新用户配置文件数据
- 具有用户配置文件权限
- 创建跨集群 API 密钥
- 更新跨集群 API 密钥
- 快照和还原 API
- 快照生命周期管理 API
- SQL API
- 同义词 API
- 文本结构 API
- 转换 API
- 使用情况 API
- Watcher API
- 定义
- 迁移指南
- 发行说明
- Elasticsearch 版本 8.17.0
- Elasticsearch 版本 8.16.1
- Elasticsearch 版本 8.16.0
- Elasticsearch 版本 8.15.5
- Elasticsearch 版本 8.15.4
- Elasticsearch 版本 8.15.3
- Elasticsearch 版本 8.15.2
- Elasticsearch 版本 8.15.1
- Elasticsearch 版本 8.15.0
- Elasticsearch 版本 8.14.3
- Elasticsearch 版本 8.14.2
- Elasticsearch 版本 8.14.1
- Elasticsearch 版本 8.14.0
- Elasticsearch 版本 8.13.4
- Elasticsearch 版本 8.13.3
- Elasticsearch 版本 8.13.2
- Elasticsearch 版本 8.13.1
- Elasticsearch 版本 8.13.0
- Elasticsearch 版本 8.12.2
- Elasticsearch 版本 8.12.1
- Elasticsearch 版本 8.12.0
- Elasticsearch 版本 8.11.4
- Elasticsearch 版本 8.11.3
- Elasticsearch 版本 8.11.2
- Elasticsearch 版本 8.11.1
- Elasticsearch 版本 8.11.0
- Elasticsearch 版本 8.10.4
- Elasticsearch 版本 8.10.3
- Elasticsearch 版本 8.10.2
- Elasticsearch 版本 8.10.1
- Elasticsearch 版本 8.10.0
- Elasticsearch 版本 8.9.2
- Elasticsearch 版本 8.9.1
- Elasticsearch 版本 8.9.0
- Elasticsearch 版本 8.8.2
- Elasticsearch 版本 8.8.1
- Elasticsearch 版本 8.8.0
- Elasticsearch 版本 8.7.1
- Elasticsearch 版本 8.7.0
- Elasticsearch 版本 8.6.2
- Elasticsearch 版本 8.6.1
- Elasticsearch 版本 8.6.0
- Elasticsearch 版本 8.5.3
- Elasticsearch 版本 8.5.2
- Elasticsearch 版本 8.5.1
- Elasticsearch 版本 8.5.0
- Elasticsearch 版本 8.4.3
- Elasticsearch 版本 8.4.2
- Elasticsearch 版本 8.4.1
- Elasticsearch 版本 8.4.0
- Elasticsearch 版本 8.3.3
- Elasticsearch 版本 8.3.2
- Elasticsearch 版本 8.3.1
- Elasticsearch 版本 8.3.0
- Elasticsearch 版本 8.2.3
- Elasticsearch 版本 8.2.2
- Elasticsearch 版本 8.2.1
- Elasticsearch 版本 8.2.0
- Elasticsearch 版本 8.1.3
- Elasticsearch 版本 8.1.2
- Elasticsearch 版本 8.1.1
- Elasticsearch 版本 8.1.0
- Elasticsearch 版本 8.0.1
- Elasticsearch 版本 8.0.0
- Elasticsearch 版本 8.0.0-rc2
- Elasticsearch 版本 8.0.0-rc1
- Elasticsearch 版本 8.0.0-beta1
- Elasticsearch 版本 8.0.0-alpha2
- Elasticsearch 版本 8.0.0-alpha1
- 依赖项和版本
多字段匹配查询
编辑多字段匹配查询
编辑multi_match
查询建立在 match
查询 的基础上,允许进行多字段查询。
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'this is a test', 'fields' => [ 'subject', 'message', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "this is a test", "fields": [ "subject", "message" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'this is a test', fields: [ 'subject', 'message' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "this is a test", "fields": [ "subject", "message" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "this is a test", fields: ["subject", "message"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "this is a test", "fields": [ "subject", "message" ] } } }
fields
和每个字段的加权
编辑可以使用通配符指定字段,例如
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'Will Smith', 'fields' => [ 'title', '*_name', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "Will Smith", "fields": [ "title", "*_name" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'Will Smith', fields: [ 'title', '*_name' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "Will Smith", "fields": [ "title", "*_name" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "Will Smith", fields: ["title", "*_name"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "fields": [ "title", "*_name" ] } } }
可以使用插入符号 (^
) 表示法对单个字段进行加权。
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'this is a test', 'fields' => [ 'subject^3', 'message', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "this is a test", "fields": [ "subject^3", "message" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'this is a test', fields: [ 'subject^3', 'message' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "this is a test", "fields": [ "subject^3", "message" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "this is a test", fields: ["subject^3", "message"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query" : "this is a test", "fields" : [ "subject^3", "message" ] } } }
如果没有提供 fields
,multi_match
查询默认使用 index.query.default_field
索引设置,该设置又默认使用 *
。*
会提取映射中所有符合词项查询条件的字段,并过滤元数据字段。然后将所有提取的字段组合起来构建一个查询。
字段数量限制
默认情况下,查询可以包含的子句数量有限制。此限制由 indices.query.bool.max_clause_count
设置定义,该设置默认为 4096
。对于多字段匹配查询,子句的数量计算为字段数量乘以词项数量。
multi_match
查询的类型
编辑multi_match
查询的内部执行方式取决于 type
参数,可以将其设置为:
|
(默认)查找与任何字段匹配的文档,但使用最佳字段的 |
|
查找与任何字段匹配的文档,并组合每个字段的 |
|
将具有相同 |
|
在每个字段上运行 |
|
在每个字段上运行 |
|
在每个字段上创建一个 |
best_fields
编辑当您搜索在同一字段中找到的最佳的多个单词时,best_fields
类型最有用。例如,单个字段中的“brown fox”比一个字段中的“brown”和另一个字段中的“fox”更有意义。
best_fields
类型为每个字段生成一个 match
查询,并将它们包装在一个 dis_max
查询中,以查找单个最佳匹配字段。例如,此查询
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'brown fox', 'type' => 'best_fields', 'fields' => [ 'subject', 'message', ], 'tie_breaker' => 0.3, ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "brown fox", "type": "best_fields", "fields": [ "subject", "message" ], "tie_breaker": 0.3 } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'brown fox', type: 'best_fields', fields: [ 'subject', 'message' ], tie_breaker: 0.3 } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "brown fox", "type": "best_fields", "fields": [ "subject", "message" ], "tie_breaker": 0.3 } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "brown fox", type: "best_fields", fields: ["subject", "message"], tie_breaker: 0.3, }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "brown fox", "type": "best_fields", "fields": [ "subject", "message" ], "tie_breaker": 0.3 } } }
将执行为
$params = [ 'body' => [ 'query' => [ 'dis_max' => [ 'queries' => [ [ 'match' => [ 'subject' => 'brown fox', ], ], [ 'match' => [ 'message' => 'brown fox', ], ], ], 'tie_breaker' => 0.3, ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "dis_max": { "queries": [ { "match": { "subject": "brown fox" } }, { "match": { "message": "brown fox" } } ], "tie_breaker": 0.3 } }, ) print(resp)
response = client.search( body: { query: { dis_max: { queries: [ { match: { subject: 'brown fox' } }, { match: { message: 'brown fox' } } ], tie_breaker: 0.3 } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "dis_max": { "queries": [ { "match": { "subject": "brown fox" } }, { "match": { "message": "brown fox" } } ], "tie_breaker": 0.3 } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { dis_max: { queries: [ { match: { subject: "brown fox", }, }, { match: { message: "brown fox", }, }, ], tie_breaker: 0.3, }, }, }); console.log(response);
GET /_search { "query": { "dis_max": { "queries": [ { "match": { "subject": "brown fox" }}, { "match": { "message": "brown fox" }} ], "tie_breaker": 0.3 } } }
通常,best_fields
类型使用单个最佳匹配字段的分数,但是如果指定了 tie_breaker
,则它将按如下方式计算分数
- 最佳匹配字段的分数
- 加上
tie_breaker * _score
用于所有其他匹配字段
此外,还接受 analyzer
、boost
、operator
、minimum_should_match
、fuzziness
、lenient
、prefix_length
、max_expansions
、fuzzy_rewrite
、zero_terms_query
、auto_generate_synonyms_phrase_query
和 fuzzy_transpositions
,如 match 查询 中所述。
operator
和 minimum_should_match
best_fields
和 most_fields
类型是以字段为中心的 — 它们为每个字段生成一个 match
查询。这意味着 operator
和 minimum_should_match
参数分别应用于每个字段,这可能不是您想要的。
以这个查询为例
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'Will Smith', 'type' => 'best_fields', 'fields' => [ 'first_name', 'last_name', ], 'operator' => 'and', ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "Will Smith", "type": "best_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'Will Smith', type: 'best_fields', fields: [ 'first_name', 'last_name' ], operator: 'and' } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "Will Smith", "type": "best_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "Will Smith", type: "best_fields", fields: ["first_name", "last_name"], operator: "and", }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "type": "best_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } } }
此查询的执行方式如下
(+first_name:will +first_name:smith) | (+last_name:will +last_name:smith)
换句话说,文档要匹配,所有词项必须在单个字段中存在。
combined_fields
查询提供了一种以词项为中心的方法,可以在每个词项的基础上处理 operator
和 minimum_should_match
。另一种多字段匹配模式 cross_fields
也解决了这个问题。
most_fields
编辑当查询以不同方式分析的包含相同文本的多个字段时,most_fields
类型最有用。例如,主字段可能包含同义词、词干和不带变音符号的词项。第二个字段可能包含原始词项,而第三个字段可能包含 shingles。通过组合来自所有三个字段的分数,我们可以使用主字段匹配尽可能多的文档,但使用第二个和第三个字段将最相似的结果推到列表的顶部。
此查询
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'quick brown fox', 'type' => 'most_fields', 'fields' => [ 'title', 'title.original', 'title.shingles', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "quick brown fox", "type": "most_fields", "fields": [ "title", "title.original", "title.shingles" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'quick brown fox', type: 'most_fields', fields: [ 'title', 'title.original', 'title.shingles' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "quick brown fox", "type": "most_fields", "fields": [ "title", "title.original", "title.shingles" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "quick brown fox", type: "most_fields", fields: ["title", "title.original", "title.shingles"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "quick brown fox", "type": "most_fields", "fields": [ "title", "title.original", "title.shingles" ] } } }
将执行为
$params = [ 'body' => [ 'query' => [ 'bool' => [ 'should' => [ [ 'match' => [ 'title' => 'quick brown fox', ], ], [ 'match' => [ 'title.original' => 'quick brown fox', ], ], [ 'match' => [ 'title.shingles' => 'quick brown fox', ], ], ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "bool": { "should": [ { "match": { "title": "quick brown fox" } }, { "match": { "title.original": "quick brown fox" } }, { "match": { "title.shingles": "quick brown fox" } } ] } }, ) print(resp)
response = client.search( body: { query: { bool: { should: [ { match: { title: 'quick brown fox' } }, { match: { 'title.original' => 'quick brown fox' } }, { match: { 'title.shingles' => 'quick brown fox' } } ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "bool": { "should": [ { "match": { "title": "quick brown fox" } }, { "match": { "title.original": "quick brown fox" } }, { "match": { "title.shingles": "quick brown fox" } } ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { bool: { should: [ { match: { title: "quick brown fox", }, }, { match: { "title.original": "quick brown fox", }, }, { match: { "title.shingles": "quick brown fox", }, }, ], }, }, }); console.log(response);
GET /_search { "query": { "bool": { "should": [ { "match": { "title": "quick brown fox" }}, { "match": { "title.original": "quick brown fox" }}, { "match": { "title.shingles": "quick brown fox" }} ] } } }
就像 bool
查询一样,每个 match
子句的分数会相加在一起。
此外,还接受 analyzer
、boost
、operator
、minimum_should_match
、fuzziness
、lenient
、prefix_length
、max_expansions
、fuzzy_rewrite
和 zero_terms_query
。
phrase
和 phrase_prefix
编辑phrase
和 phrase_prefix
类型的行为与 best_fields
类似,但它们使用 match_phrase
或 match_phrase_prefix
查询而不是 match
查询。
此查询
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'quick brown f', 'type' => 'phrase_prefix', 'fields' => [ 'subject', 'message', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "quick brown f", "type": "phrase_prefix", "fields": [ "subject", "message" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'quick brown f', type: 'phrase_prefix', fields: [ 'subject', 'message' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "quick brown f", "type": "phrase_prefix", "fields": [ "subject", "message" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "quick brown f", type: "phrase_prefix", fields: ["subject", "message"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "quick brown f", "type": "phrase_prefix", "fields": [ "subject", "message" ] } } }
将执行为
$params = [ 'body' => [ 'query' => [ 'dis_max' => [ 'queries' => [ [ 'match_phrase_prefix' => [ 'subject' => 'quick brown f', ], ], [ 'match_phrase_prefix' => [ 'message' => 'quick brown f', ], ], ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "dis_max": { "queries": [ { "match_phrase_prefix": { "subject": "quick brown f" } }, { "match_phrase_prefix": { "message": "quick brown f" } } ] } }, ) print(resp)
response = client.search( body: { query: { dis_max: { queries: [ { match_phrase_prefix: { subject: 'quick brown f' } }, { match_phrase_prefix: { message: 'quick brown f' } } ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "dis_max": { "queries": [ { "match_phrase_prefix": { "subject": "quick brown f" } }, { "match_phrase_prefix": { "message": "quick brown f" } } ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { dis_max: { queries: [ { match_phrase_prefix: { subject: "quick brown f", }, }, { match_phrase_prefix: { message: "quick brown f", }, }, ], }, }, }); console.log(response);
GET /_search { "query": { "dis_max": { "queries": [ { "match_phrase_prefix": { "subject": "quick brown f" }}, { "match_phrase_prefix": { "message": "quick brown f" }} ] } } }
此外,还接受 Match 中所述的 analyzer
、boost
、lenient
和 zero_terms_query
,以及 Match phrase 中所述的 slop
。类型 phrase_prefix
另外接受 max_expansions
。
cross_fields
编辑对于多个字段应该匹配的结构化文档,cross_fields
类型特别有用。例如,当查询“Will Smith”的 first_name
和 last_name
字段时,最佳匹配很可能在一个字段中具有“Will”,而在另一个字段中具有“Smith”。
处理这些类型查询的一种方法是简单地将 first_name
和 last_name
字段索引到一个 full_name
字段中。当然,这只能在索引时完成。
cross_field
类型尝试通过采用以词项为中心的方法在查询时解决这些问题。它首先将查询字符串分析为单个词项,然后在任何字段中查找每个词项,就像它们是一个大字段一样。
类似这样的查询
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'Will Smith', 'type' => 'cross_fields', 'fields' => [ 'first_name', 'last_name', ], 'operator' => 'and', ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "Will Smith", "type": "cross_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'Will Smith', type: 'cross_fields', fields: [ 'first_name', 'last_name' ], operator: 'and' } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "Will Smith", "type": "cross_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "Will Smith", type: "cross_fields", fields: ["first_name", "last_name"], operator: "and", }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "Will Smith", "type": "cross_fields", "fields": [ "first_name", "last_name" ], "operator": "and" } } }
将执行为
+(first_name:will last_name:will) +(first_name:smith last_name:smith)
换句话说,文档要匹配,所有词项必须在至少一个字段中存在。(将其与best_fields
和 most_fields
使用的逻辑进行比较。)
这解决了两个问题之一。为了平衡差异,通过混合所有字段的词项频率来解决词项频率不同的问题。
实际上,first_name:smith
将被视为具有与 last_name:smith
相同的频率,加一。这将使 first_name
和 last_name
上的匹配具有可比较的分数,并且由于 last_name
是最有可能包含 smith
的字段,因此它略有优势。
请注意,cross_fields
通常只对所有 boost
值都为 1
的短字符串字段有用。否则,boost、词频和长度归一化会以一种方式影响得分,使得词项统计的混合不再有意义。
如果您通过 验证 API 运行以上查询,它将返回此解释:
+blended("will", fields: [first_name, last_name]) +blended("smith", fields: [first_name, last_name])
此外,还接受 analyzer
、boost
、operator
、minimum_should_match
、lenient
和 zero_terms_query
。
cross_fields
类型以一种复杂的、难以解释的方式混合字段统计信息。得分组合甚至可能不正确,尤其是在某些文档包含某些搜索字段,但并非全部搜索字段时。您应该考虑使用 combined_fields
查询作为替代方案,它也是以词项为中心,但以更稳健的方式组合字段统计信息。
cross_field
和分析
编辑cross_field
类型只能在以词项为中心的模式下工作,且字段必须具有相同的分析器。具有相同分析器的字段会像上面的示例一样被分组在一起。如果存在多个组,则查询将使用任何组中的最佳得分。
例如,如果我们有一个 first
和 last
字段,它们具有相同的分析器,以及一个 first.edge
和 last.edge
字段,它们都使用 edge_ngram
分析器,那么这个查询:
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'Jon', 'type' => 'cross_fields', 'fields' => [ 'first', 'first.edge', 'last', 'last.edge', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "Jon", "type": "cross_fields", "fields": [ "first", "first.edge", "last", "last.edge" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'Jon', type: 'cross_fields', fields: [ 'first', 'first.edge', 'last', 'last.edge' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "Jon", "type": "cross_fields", "fields": [ "first", "first.edge", "last", "last.edge" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "Jon", type: "cross_fields", fields: ["first", "first.edge", "last", "last.edge"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "Jon", "type": "cross_fields", "fields": [ "first", "first.edge", "last", "last.edge" ] } } }
将执行为
blended("jon", fields: [first, last]) | ( blended("j", fields: [first.edge, last.edge]) blended("jo", fields: [first.edge, last.edge]) blended("jon", fields: [first.edge, last.edge]) )
换句话说,first
和 last
将被分组在一起并被视为单个字段,而 first.edge
和 last.edge
将被分组在一起并被视为单个字段。
拥有多个组是可以的,但是当与 operator
或 minimum_should_match
结合使用时,它会遇到与 most_fields
或 best_fields
相同的问题。
您可以轻松地将此查询重写为两个单独的 cross_fields
查询,并使用 dis_max
查询组合,并将 minimum_should_match
参数仅应用于其中一个查询。
resp = client.search( query={ "dis_max": { "queries": [ { "multi_match": { "query": "Will Smith", "type": "cross_fields", "fields": [ "first", "last" ], "minimum_should_match": "50%" } }, { "multi_match": { "query": "Will Smith", "type": "cross_fields", "fields": [ "*.edge" ] } } ] } }, ) print(resp)
response = client.search( body: { query: { dis_max: { queries: [ { multi_match: { query: 'Will Smith', type: 'cross_fields', fields: [ 'first', 'last' ], minimum_should_match: '50%' } }, { multi_match: { query: 'Will Smith', type: 'cross_fields', fields: [ '*.edge' ] } } ] } } } ) puts response
const response = await client.search({ query: { dis_max: { queries: [ { multi_match: { query: "Will Smith", type: "cross_fields", fields: ["first", "last"], minimum_should_match: "50%", }, }, { multi_match: { query: "Will Smith", type: "cross_fields", fields: ["*.edge"], }, }, ], }, }, }); console.log(response);
GET /_search { "query": { "dis_max": { "queries": [ { "multi_match" : { "query": "Will Smith", "type": "cross_fields", "fields": [ "first", "last" ], "minimum_should_match": "50%" } }, { "multi_match" : { "query": "Will Smith", "type": "cross_fields", "fields": [ "*.edge" ] } } ] } } }
您可以通过在查询中指定 analyzer
参数来强制将所有字段放入同一组中。
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'Jon', 'type' => 'cross_fields', 'analyzer' => 'standard', 'fields' => [ 'first', 'last', '*.edge', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "Jon", "type": "cross_fields", "analyzer": "standard", "fields": [ "first", "last", "*.edge" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'Jon', type: 'cross_fields', analyzer: 'standard', fields: [ 'first', 'last', '*.edge' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "Jon", "type": "cross_fields", "analyzer": "standard", "fields": [ "first", "last", "*.edge" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "Jon", type: "cross_fields", analyzer: "standard", fields: ["first", "last", "*.edge"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "Jon", "type": "cross_fields", "analyzer": "standard", "fields": [ "first", "last", "*.edge" ] } } }
这将像以下方式执行:
blended("will", fields: [first, first.edge, last.edge, last]) blended("smith", fields: [first, first.edge, last.edge, last])
tie_breaker
编辑默认情况下,每个词项的 blended
查询将使用组中任何字段返回的最佳得分。然后在跨组组合得分时,查询将使用任何组中的最佳得分。tie_breaker
参数可以更改这两个步骤的行为。
|
从(例如) |
|
将(例如) |
|
选取单个最佳得分,再加上 |
bool_prefix
编辑bool_prefix
类型的评分行为类似于 most_fields
,但使用的是 match_bool_prefix
查询而不是 match
查询。
$params = [ 'body' => [ 'query' => [ 'multi_match' => [ 'query' => 'quick brown f', 'type' => 'bool_prefix', 'fields' => [ 'subject', 'message', ], ], ], ], ]; $response = $client->search($params);
resp = client.search( query={ "multi_match": { "query": "quick brown f", "type": "bool_prefix", "fields": [ "subject", "message" ] } }, ) print(resp)
response = client.search( body: { query: { multi_match: { query: 'quick brown f', type: 'bool_prefix', fields: [ 'subject', 'message' ] } } } ) puts response
res, err := es.Search( es.Search.WithBody(strings.NewReader(`{ "query": { "multi_match": { "query": "quick brown f", "type": "bool_prefix", "fields": [ "subject", "message" ] } } }`)), es.Search.WithPretty(), ) fmt.Println(res, err)
const response = await client.search({ query: { multi_match: { query: "quick brown f", type: "bool_prefix", fields: ["subject", "message"], }, }, }); console.log(response);
GET /_search { "query": { "multi_match" : { "query": "quick brown f", "type": "bool_prefix", "fields": [ "subject", "message" ] } } }
支持 match 查询中解释的 analyzer
、boost
、operator
、minimum_should_match
、lenient
、zero_terms_query
和 auto_generate_synonyms_phrase_query
参数。 fuzziness
、prefix_length
、max_expansions
、fuzzy_rewrite
和 fuzzy_transpositions
参数支持用于构造词项查询的词项,但对从最终词项构造的前缀查询没有影响。
此查询类型不支持 slop
参数。
On this page