- 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
- 依赖项和版本
显著文本聚合
编辑显著文本聚合
编辑一种聚合,返回集合中自由文本词条中有趣或不寻常的出现。它类似于显著词条聚合,但不同之处在于:
- 它专门设计用于
text
类型的字段。 - 它不需要字段数据或 doc-values。
- 它会动态地重新分析文本内容,这意味着它还可以过滤掉嘈杂文本中重复的部分,否则这些部分会歪曲统计数据。
示例用例
- 当用户搜索“禽流感”时,建议“H5N1”以帮助扩展查询
- 建议与股票代码 $ATI 相关的关键字,用于自动新闻分类器
在这些情况下,选择的词条不仅仅是结果中最流行的词条。最流行的词往往非常无聊(and、of、the、we、I、they ...)。显著词条是在前景和背景集之间衡量流行度发生显著变化的词条。如果“H5N1”这个词在 1000 万个文档的索引中只存在于 5 个文档中,但在构成用户搜索结果的 100 个文档中却有 4 个文档包含该词,那么这很重要,并且可能与他们的搜索非常相关。5/10,000,000 与 4/100 相比,频率变化很大。
基本用法
编辑在典型的用例中,感兴趣的前景集合是查询的匹配度最高的搜索结果的选择,而用于统计比较的背景集合是收集结果的索引或多个索引。
示例
resp = client.search( index="news", query={ "match": { "content": "Bird flu" } }, aggregations={ "my_sample": { "sampler": { "shard_size": 100 }, "aggregations": { "keywords": { "significant_text": { "field": "content" } } } } }, ) print(resp)
response = client.search( index: 'news', body: { query: { match: { content: 'Bird flu' } }, aggregations: { my_sample: { sampler: { shard_size: 100 }, aggregations: { keywords: { significant_text: { field: 'content' } } } } } } ) puts response
const response = await client.search({ index: "news", query: { match: { content: "Bird flu", }, }, aggregations: { my_sample: { sampler: { shard_size: 100, }, aggregations: { keywords: { significant_text: { field: "content", }, }, }, }, }, }); console.log(response);
GET news/_search { "query": { "match": { "content": "Bird flu" } }, "aggregations": { "my_sample": { "sampler": { "shard_size": 100 }, "aggregations": { "keywords": { "significant_text": { "field": "content" } } } } } }
响应
{ "took": 9, "timed_out": false, "_shards": ..., "hits": ..., "aggregations" : { "my_sample": { "doc_count": 100, "keywords" : { "doc_count": 100, "buckets" : [ { "key": "h5n1", "doc_count": 4, "score": 4.71235374214817, "bg_count": 5 } ... ] } } } }
结果表明,“h5n1”是与禽流感密切相关的几个词条之一。它在我们的整个索引中只出现 5 次(请参阅 bg_count
),但在我们 100 个“禽流感”结果文档样本中,有幸出现 4 次。这表明这是一个重要的词,用户可能会将其添加到他们的搜索中。
使用 filter_duplicate_text
处理嘈杂数据
编辑自由文本字段通常包含原始内容和文本的机械副本(复制粘贴的传记、电子邮件回复链、转推、样板页眉/页脚、页面导航菜单、侧边栏新闻链接、版权声明、标准免责声明、地址)。
在实际数据中,如果不进行过滤,这些重复的文本部分往往会在 significant_text
结果中大量出现。在索引时过滤近乎重复的文本是一项艰巨的任务,但我们可以使用 filter_duplicate_text
设置在查询时动态清理数据。
首先,让我们使用Signal 媒体数据集(包含 100 万篇涵盖各种新闻的新闻文章),查看一个未过滤的实际示例。以下是搜索提及“elasticsearch”的文章的原始显著文本结果
{ ... "aggregations": { "sample": { "doc_count": 35, "keywords": { "doc_count": 35, "buckets": [ { "key": "elasticsearch", "doc_count": 35, "score": 28570.428571428572, "bg_count": 35 }, ... { "key": "currensee", "doc_count": 8, "score": 6530.383673469388, "bg_count": 8 }, ... { "key": "pozmantier", "doc_count": 4, "score": 3265.191836734694, "bg_count": 4 }, ... }
未经清理的文档出现了一些看起来很奇怪的词条,这些词条表面上与我们的搜索词“elasticsearch”的出现具有统计相关性,例如“pozmantier”。我们可以深入研究这些文档的示例,以了解为什么 pozmantier 是通过此查询连接的
resp = client.search( index="news", query={ "simple_query_string": { "query": "+elasticsearch +pozmantier" } }, source=[ "title", "source" ], highlight={ "fields": { "content": {} } }, ) print(resp)
response = client.search( index: 'news', body: { query: { simple_query_string: { query: '+elasticsearch +pozmantier' } }, _source: [ 'title', 'source' ], highlight: { fields: { content: {} } } } ) puts response
const response = await client.search({ index: "news", query: { simple_query_string: { query: "+elasticsearch +pozmantier", }, }, _source: ["title", "source"], highlight: { fields: { content: {}, }, }, }); console.log(response);
GET news/_search { "query": { "simple_query_string": { "query": "+elasticsearch +pozmantier" } }, "_source": [ "title", "source" ], "highlight": { "fields": { "content": {} } } }
结果显示了一系列关于多个技术项目评审小组的非常相似的新闻文章
{ ... "hits": { "hits": [ { ... "_source": { "source": "Presentation Master", "title": "T.E.N. Announces Nominees for the 2015 ISE® North America Awards" }, "highlight": { "content": [ "City of San Diego Mike <em>Pozmantier</em>, Program Manager, Cyber Security Division, Department of", " Janus, Janus <em>ElasticSearch</em> Security Visualization Engine " ] } }, { ... "_source": { "source": "RCL Advisors", "title": "T.E.N. Announces Nominees for the 2015 ISE(R) North America Awards" }, "highlight": { "content": [ "Mike <em>Pozmantier</em>, Program Manager, Cyber Security Division, Department of Homeland Security S&T", "Janus, Janus <em>ElasticSearch</em> Security Visualization Engine" ] } }, ...
Mike Pozmantier 是评审小组的众多评委之一,而 elasticsearch 被用于正在评审的多个项目之一。
通常情况下,此篇冗长的新闻稿被多个新闻站点复制粘贴,因此其中包含的任何罕见名称、数字或拼写错误都会与我们匹配的查询在统计上相关联。
幸运的是,相似的文档往往排名相似,因此,作为检查匹配度最高的文档流的一部分,significant_text 聚合可以应用过滤器来删除已出现过的任何 6 个或更多令牌的序列。现在,让我们尝试相同的查询,但启用 filter_duplicate_text
设置
resp = client.search( index="news", query={ "match": { "content": "elasticsearch" } }, aggs={ "sample": { "sampler": { "shard_size": 100 }, "aggs": { "keywords": { "significant_text": { "field": "content", "filter_duplicate_text": True } } } } }, ) print(resp)
response = client.search( index: 'news', body: { query: { match: { content: 'elasticsearch' } }, aggregations: { sample: { sampler: { shard_size: 100 }, aggregations: { keywords: { significant_text: { field: 'content', filter_duplicate_text: true } } } } } } ) puts response
const response = await client.search({ index: "news", query: { match: { content: "elasticsearch", }, }, aggs: { sample: { sampler: { shard_size: 100, }, aggs: { keywords: { significant_text: { field: "content", filter_duplicate_text: true, }, }, }, }, }, }); console.log(response);
GET news/_search { "query": { "match": { "content": "elasticsearch" } }, "aggs": { "sample": { "sampler": { "shard_size": 100 }, "aggs": { "keywords": { "significant_text": { "field": "content", "filter_duplicate_text": true } } } } } }
对于任何熟悉 elastic stack 的人来说,分析重复数据删除后的文本的结果显然质量更高
{ ... "aggregations": { "sample": { "doc_count": 35, "keywords": { "doc_count": 35, "buckets": [ { "key": "elasticsearch", "doc_count": 22, "score": 11288.001166180758, "bg_count": 35 }, { "key": "logstash", "doc_count": 3, "score": 1836.648979591837, "bg_count": 4 }, { "key": "kibana", "doc_count": 3, "score": 1469.3020408163263, "bg_count": 5 } ] } } } }
由于复制粘贴操作或其他形式的机械重复,Pozmantier 先生和其他与 elasticsearch 的一次性关联不再出现在聚合结果中。
如果可以通过单值索引字段(可能是文章的 title
文本或 original_press_release_url
字段的哈希)来识别重复或近乎重复的内容,则使用父多样化采样器聚合来基于该单个键从样本集中消除这些文档会更有效。预先馈送到 significant_text 聚合的重复内容越少,性能就越好。
限制
编辑不支持子聚合
编辑significant_text 聚合故意不支持添加子聚合,因为
- 它会带来很高的内存成本
- 它不是一个普遍有用的功能,并且对于那些需要它的用户有一个解决方法
候选词条的数量通常非常多,并且在返回最终结果之前会对其进行大量修剪。支持子聚合会产生额外的搅动,并且效率低下。客户端始终可以从 significant_text
请求中获取经过大量修剪的结果集,并使用带有 include
子句和子聚合的 terms
聚合进行后续查询,以更有效的方式对选定的关键字进行进一步分析。
不支持嵌套对象
编辑significant_text 聚合当前也不能与嵌套对象中的文本字段一起使用,因为它使用文档 JSON 源。考虑到匹配的 Lucene docID,这使得从存储的 JSON 中匹配嵌套文档时,此功能的效率很低。
近似计数
编辑结果中提供的包含词条的文档数量基于对每个分片返回的样本求和,因此可能
- 如果某些分片未在其顶部样本中提供给定词条的数字,则较低
- 在考虑背景频率时较高,因为它可能会计算已删除文档中找到的出现次数
与大多数设计决策一样,这是权衡的基础,我们选择以牺牲一些(通常很小)的不准确性为代价来提供快速性能。但是,下一节中介绍的 size
和 shard size
设置提供了有助于控制准确性级别的工具。
参数
编辑大小 & 分片大小
编辑可以设置 size
参数,以定义应从整体词条列表中返回多少个词条桶。默认情况下,协调搜索过程的节点将请求每个分片提供其自己的顶部词条桶,并且一旦所有分片都响应,它会将结果减少到最终列表,然后将该列表返回给客户端。如果唯一词条的数量大于 size
,则返回的列表可能略有偏差且不准确(可能是词条计数略有偏差,甚至可能是本应在顶部大小桶中的词条未返回)。
为了确保更高的准确性,最终 size
的倍数用作从每个分片请求的词条数量 (2 * (size * 1.5 + 10)
)。要手动控制此设置,可以使用 shard_size
参数来控制每个分片生成的候选词条的数量。
一旦合并所有结果,低频词条可能会变成最有趣的词条,因此,当 shard_size
参数设置为明显高于 size
设置的值时,significant_terms 聚合可以产生更高质量的结果。这确保了由减少节点对更多有希望的候选词条进行整合审查,然后再进行最终选择。显然,大型候选词条列表会导致额外的网络流量和 RAM 使用率,因此这需要在质量/成本之间进行权衡。如果 shard_size
设置为 -1(默认值),则将根据分片数量和 size
参数自动估算 shard_size
。
shard_size
不能小于 size
(因为这没有意义)。如果小于,Elasticsearch 将会覆盖它,并将其重置为等于 size
。
最小文档计数
编辑可以使用 min_doc_count
选项来配置只返回匹配超过指定命中次数的词条。默认值为 3。
得分较高的词条将在分片级别进行收集,并在第二步中与从其他分片收集的词条合并。然而,分片没有关于全局词条频率的信息。是否将一个词条添加到候选列表的决定仅取决于使用本地分片频率计算的分片上的得分,而不是词条的全局频率。min_doc_count
标准仅在合并所有分片的本地词条统计信息后应用。在某种程度上,添加词条作为候选的决定是在不确定该词条是否会实际达到要求的 min_doc_count
的情况下做出的。如果低频但得分高的词条填充了候选列表,这可能会导致许多(全局)高频词条在最终结果中丢失。为了避免这种情况,可以增加 shard_size
参数,以允许分片上有更多的候选词条。然而,这会增加内存消耗和网络流量。
shard_min_doc_count
编辑参数 shard_min_doc_count
调节分片在确定词条是否应该根据 min_doc_count
添加到候选列表时的确定性。只有当词条在集合中的本地分片频率高于 shard_min_doc_count
时,才会考虑该词条。如果你的字典包含许多低频词条,并且你对这些词条不感兴趣(例如拼写错误),那么你可以设置 shard_min_doc_count
参数来过滤掉分片级别的候选词条,这些词条即使在合并本地计数后也几乎肯定不会达到要求的 min_doc_count
。shard_min_doc_count
默认设置为 0
,除非你显式设置它,否则不会生效。
通常不建议将 min_doc_count
设置为 1
,因为它倾向于返回拼写错误或其他奇怪的词条。找到一个词条的多个实例有助于加强这一观点,即虽然罕见,但该词条并非一次性意外的结果。默认值 3 用于提供最小的证据权重。将 shard_min_doc_count
设置得太高会导致重要的候选词条在分片级别被过滤掉。此值应设置得远低于 min_doc_count/#shards
。
自定义背景上下文
编辑背景词条频率的默认统计信息来源是整个索引,可以通过使用 background_filter
来缩小此范围,以关注更窄上下文中的重要词条。
resp = client.search( index="news", query={ "match": { "content": "madrid" } }, aggs={ "tags": { "significant_text": { "field": "content", "background_filter": { "term": { "content": "spain" } } } } }, ) print(resp)
response = client.search( index: 'news', body: { query: { match: { content: 'madrid' } }, aggregations: { tags: { significant_text: { field: 'content', background_filter: { term: { content: 'spain' } } } } } } ) puts response
const response = await client.search({ index: "news", query: { match: { content: "madrid", }, }, aggs: { tags: { significant_text: { field: "content", background_filter: { term: { content: "spain", }, }, }, }, }, }); console.log(response);
GET news/_search { "query": { "match": { "content": "madrid" } }, "aggs": { "tags": { "significant_text": { "field": "content", "background_filter": { "term": { "content": "spain" } } } } } }
上面的过滤器将有助于关注马德里市特有的词条,而不是显示像“西班牙语”这样的词条,这些词条在整个索引的全球背景下是不寻常的,但在包含“西班牙”一词的文档子集中是很常见的。
使用背景过滤器会减慢查询速度,因为必须过滤每个词条的倒排表以确定频率。
处理源和索引映射
编辑通常,索引字段名称和检索的原始 JSON 字段共享相同的名称。然而,对于更复杂的字段映射,使用诸如 copy_to
等功能,源 JSON 字段和聚合的索引字段可能会有所不同。在这些情况下,可以使用 source_fields
参数列出将从中分析文本的 JSON _source 字段。
resp = client.search( index="news", query={ "match": { "custom_all": "elasticsearch" } }, aggs={ "tags": { "significant_text": { "field": "custom_all", "source_fields": [ "content", "title" ] } } }, ) print(resp)
response = client.search( index: 'news', body: { query: { match: { custom_all: 'elasticsearch' } }, aggregations: { tags: { significant_text: { field: 'custom_all', source_fields: [ 'content', 'title' ] } } } } ) puts response
const response = await client.search({ index: "news", query: { match: { custom_all: "elasticsearch", }, }, aggs: { tags: { significant_text: { field: "custom_all", source_fields: ["content", "title"], }, }, }, }); console.log(response);
GET news/_search { "query": { "match": { "custom_all": "elasticsearch" } }, "aggs": { "tags": { "significant_text": { "field": "custom_all", "source_fields": [ "content", "title" ] } } } }
On this page