【问题标题】:Elasticsearch store field vs _sourceElasticsearch 存储字段与 _source
【发布时间】:2019-09-26 20:03:01
【问题描述】:

使用 Elasticsearch 1.4.3

我正在构建一种“报告”系统。客户可以选择他们希望在结果中返回哪些字段。

在 90% 的情况下,客户端永远不会选择所有字段,所以我想我可以在映射中禁用 _source 字段以节省空间。但后来我知道了

GET myIndex/myType/_search/
{
    "fields": ["field1", "field2"]
    ...
}

不返回字段。

所以我假设我必须对每个字段使用 "store": true 。从我读到的内容来看,这对于搜索来说会更快,但我猜在空间方面它会与 _source 相同,或者我们仍然可以节省空间?

【问题讨论】:

  • 我做了一些测试。插入 4 种类型 x 每种 100,000 = 每个索引 400,000。 _source: true = 45MB _source: true, _all: false = 34MB _source: false = 30MB _source: false, _all: false = 18MB _source: false, store: true (所有字段) = 39.5MB _source: false, store: true (所有字段),_all:false = 28.5MB

标签: elasticsearch


【解决方案1】:

_source 字段存储您发送到 Elasticsearch 的 JSON,您可以选择仅在需要时返回某些字段,这非常适合您的用例。我从来没有听说存储的字段搜索速度会更快。 _source 字段在磁盘空间上可能更大,但如果您必须存储每个字段,则无需在 _source 字段上使用存储字段。如果您确实禁用了源字段,则意味着:

  • 您将无法进行部分更新
  • 您将无法从您的 JSON 中重新索引您的数据 Elasticsearch 集群,你必须从数据源重新索引 (通常会慢很多)。

【讨论】:

    【解决方案2】:

    默认情况下,在 elasticsearch 中,_source(被索引的文档)被存储。这意味着当您搜索时,您可以获得实际的文档来源。此外,elasticsearch 会自动从_source 中提取fields/objects,并在您明确要求时返回它们(以及可能在其他组件中使用它,例如突出显示)。

    您可以指定还存储特定字段。这意味着该字段的数据将单独存储。这意味着如果您请求field1(已存储),elasticsearch 将识别它已存储,并从索引中加载它,而不是从 _source 获取它(假设 _source 已启用)。

    您希望何时启用存储特定字段?大多数时候,你没有。获取_source 很快,提取它也很快。如果您有非常大的文档,存储_source 的成本或解析_source 的成本很高,您可以显式映射一些要存储的字段。

    请注意,检索每个存储字段是有成本的。因此,例如,如果您有一个包含 10 个大小合理的字段的 json,并且您将所有这些字段映射为已存储,并要求所有这些字段,这意味着加载每个字段(更多磁盘寻道),而不是仅加载 @ 987654334@(这是一个字段,可能已压缩)。

    我在下面由 shay.banon 回答的链接上得到了这个答案,你可以阅读整个帖子以更好地理解它。 enter link description here

    【讨论】:

    【解决方案3】:

    克林顿葛姆雷在下面的链接中说

    https://groups.google.com/forum/#!topic/elasticsearch/j8cfbv-j73g/discussion

    • 默认情况下,ES 将您的 JSON 文档存储在 _source 字段中,即 设置为“已存储”

    • 默认情况下,JSON 文档中的字段设置为不“存储” (即存储为单独的字段)

    • 因此,当 ES 返回您的文档(搜索或获取)时,它只需加载 _source 字段并返回,即单个磁盘查找

    有些人认为通过存储单个字段会更快 而不是从 _source 字段加载整个 JSON 文档。他们没有什么 意识到每个存储字段都需要一个磁盘查找(每次查找 10 毫秒! ),而那些寻求的总和远远超过了公正的成本 发送 _source 字段。

    换句话说,它几乎总是错误的优化。

    【讨论】:

    • 可以随机访问的数据存储介质呢?在这种情况下,来源会更有优势吗?
    【解决方案4】:

    启用 _source 会将整个 JSON 文档存储在索引中,而 store 将仅存储标记为的单个字段。因此,如果您想节省磁盘空间,使用store 可能比使用_source 更好。

    【讨论】:

    • 测试它...通过禁用源,我节省了大约 1GB 的空间(包括副本)。在所有字段上使用 store: true 似乎我仍在节省相同的空间。我想在这种情况下,存储字段是直接从索引数据访问的?
    【解决方案5】:

    作为 ES 7.3 的参考,答案变得更加清晰。 不要在您有充分的测试理由之前尝试优化在实际生产条件下

    我可能只是引用_source:

    用户经常禁用_source 字段而不考虑 后果,然后活到后悔。如果_source 字段不是 可用,则不支持许多功能:

    • update, update_by_query, 和reindex API。

    • 动态突出显示。

    • 能够从一个 Elasticsearch 索引重新索引到另一个, 更改映射或分析,或将索引升级到新专业 版本。

    • 能够通过查看原始数据来调试查询或聚合 索引时使用的文档。

    • 将来可能会修复索引损坏 自动。

    提示:如果需要考虑磁盘空间,请增加 压缩级别而不是禁用_source

    除此之外,使用stored_fields 并没有您可能想到的明显优势。

    如果您只想检索单个字段或几个字段的值,而不是整个 _source,则可以使用source filtering 来实现。

    【讨论】:

      猜你喜欢
      • 2016-02-20
      • 2018-10-12
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多