【问题标题】:Why do I need "store":"yes" in elasticsearch?为什么我在弹性搜索中需要“store”:“yes”?
【发布时间】:2013-06-10 18:45:48
【问题描述】:

我真的不明白为什么在core types link 它在属性描述中说(例如数字):

  1. store - 设置为yes 将实际字段存储在索引中,no 不存储它。默认为 no(注意,JSON 文档本身已存储,并且可以从中检索
  2. index - 如果值不应被索引,则设置为 no。在这种情况下,store 应该设置为 yes,因为如果它没有被索引并且没有被存储,没有任何关系

这两个粗体部分似乎是矛盾的。如果"index":"no", "store":"no" 我仍然可以从源中获取价值。例如,如果我有一个包含 URL 的字段,这可能是一个很好的用途。没有?

我做了一个小实验,有两个映射,一个字段设置为"store":"yes",另一个设置为"store":"no"

在这两种情况下,我仍然可以在查询中指定:

{"query":{"match_all":{}}, "fields":["my_test_field"]}

我得到了相同的答案,返回了字段。

我认为如果将"store" 设置为"no",则意味着我无法检索特定字段,但必须获取整个_source 并在客户端对其进行解析。

那么,将"store" 设置为"yes" 有什么好处?仅当我从 "_source" 字段中明确排除该字段时才相关吗?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    我认为如果“商店”设置为“否”,这意味着我不能 检索特定字段,但必须获取整个 _source 和 在客户端解析它。

    当未存储字段(默认)并且启用 _source 字段(也是默认)时,这正是 elasticsearch 为您所做的。

    您通常会向 elasticsearch 发送一个字段,因为您要么想搜索它,要么检索它。但确实,如果您不明确存储该字段并且您不禁用源,您仍然可以使用_source 检索该字段。这意味着在某些情况下,拥有一个既不被索引也不被存储的字段实际上可能是有意义的。

    当您存储一个字段时,这是在底层 lucene 中完成的。 Lucene 是一个倒排索引,它允许快速全文搜索并在给定文本查询的情况下返回文档 ID。除了倒排索引之外,Lucene 有某种存储方式,可以存储字段值,以便在给定文档 id 的情况下进行检索。您通常将要作为搜索结果返回的字段存储在 lucene 中。 Elasticsearch 不需要存储您想要返回的每个字段,因为它始终默认存储您发送给它的每个文档,因此它总是能够将您发送给它的所有内容作为搜索结果返回。

    在少数情况下,在 lucene 中显式存储字段可能很有用:当 _source 字段被禁用时,或者当我们想要避免解析它时,即使解析是由 elasticsearch 自动完成的。 请记住,尽管从 lucene 检索许多存储的字段可能需要每个字段进行一次磁盘查找,而从 lucene 仅检索 _source 并对其进行解析以检索所需字段只是一次磁盘查找,并且在大多数情况下更快案例。

    【讨论】:

    • 太棒了!谢谢你的解释。
    • "请记住,尽管从 lucene 检索许多存储的字段可能需要每个字段进行一次磁盘搜索,而仅从 lucene 检索 _source 并对其进行解析以检索所需字段只是一个磁盘在大多数情况下,寻找并且更快。”给定SSD用于存储索引,减少搜索次数的效果是否明显? “在 HDD 中,这通常在 0.2 到 0.8 毫秒之间。典型的 SSD 的寻道时间在 0.08 到 0.16 毫秒之间。”
    • 显式存储_source 中未返回的字段也很有用。时间戳就是一个例子。即使你在一个类型上启用了它们,你也无法检索它们("fields": ["_timestamp"] 将不返回任何内容),除非你有 "_timestamp": { "store": true } in您对该类型的映射。
    • ES 新手。想象一下,我为除record_id 之外的所有字段设置了“_source=false”和“store=no”。 ES 会给我什么样的功能?我能否计算具有给定字段的记录数或生成直方图?还有什么?
    • 我有一个通常约为 1MB 的字段,其余的小于 1KB,因此保存 _source 意味着需要更多的存储空间。我还在权衡 _stored 字段的 SSD 访问是否会减慢速度以满足保存 _source 的要求。
    【解决方案2】:

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

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

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

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

    Source link

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 2021-06-27
    相关资源
    最近更新 更多