【问题标题】:ElasticSearch: Impact of setting a "not_analyzed" field as "store":"yes"?ElasticSearch:将“not_analyzed”字段设置为“store”:“yes”的影响?
【发布时间】:2013-03-08 17:25:48
【问题描述】:

假设我在映射中有一个字符串字段指定为not_analyzed。如果我随后将"store":"yes" 添加到映射中,ElasticSearch 会复制存储吗?我对not_analyzed 字段的理解是,它们不是通过分析器运行的,按原样编入索引,但客户端能够与之匹配。因此,如果一个字段同时是 not_analyzedstore:yes,这可能会导致 ElasticSearch 保留字符串的两个副本。

我的问题:

  • 如果一个字符串字段同时存储为not_analyzedstore:yes,会不会出现重复存储的字符串?

我希望这已经足够清楚了。谢谢!

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您在 lucene 中混淆了索引字段和存储字段的概念,lucene 是在弹性搜索之上构建的库。

    当一个字段进入倒排索引时,它就会被索引,lucene 使用这种数据结构来提供其强大而快速的全文搜索功能。如果要搜索某个字段,则必须对其进行索引。当你索引一个字段时,你可以决定是要按原样索引它,还是要分析它,这意味着决定一个标记器应用到它,这将生成一个标记列表(单词)和一个标记列表可以修改生成的令牌(甚至添加或删除一些)的过滤器。索引字段的方式会影响您对其进行搜索的方式。如果您索引一个字段但不对其进行分析,并且其文本由多个单词组成,您将能够找到该文档仅搜索该确切的特定文本,包括空格。

    当您希望能够检索某个字段时,它会被存储。假设 Lucene 也提供了某种存储,它与倒排索引本身没有任何关系。 当你使用 lucene 搜索时,你会得到一个匹配的文档 ID 列表。然后,您可以从他们存储的字段中检索一些文本,这就是您在搜索结果中真正显示的内容。如果你不存储一个字段,你将永远无法从 lucene 中取回它(但这对于 elasticsearch 来说不是这样,我将在下面解释)。

    您可以拥有只想搜索但从不显示的字段:已编入索引且未存储(默认在 lucene 中)。
    您可以拥有要搜索和检索的字段:索引和存储。
    您可以拥有不想搜索但确实想检索以显示它们的字段。

    因此这两个数据结构彼此不相关。如果你在 lucene 中同时索引和存储一个字段,它的内容将不会以相同的形式出现两次。存储字段按原样存储,因为您将它们发送到 lucene,而索引字段可能会被分析并将成为倒排索引的一部分,这是另一回事。存储的字段用于检索特定文档(通过 lucene 文档 id),而索引字段用于搜索,在这样的结构中,从字面上反转文本,结果每个术语作为键,以及文档列表包含它的 ID(发布列表)。

    当谈到弹性搜索时,情况会发生一些变化。如果您未将字段配置为存储在映射中(默认为 store:no),则默认情况下无论如何您都可以检索它。发生这种情况是因为 elasticsearch 总是将您发送给它的整个源文档(除非您禁用此功能)存储在一个名为 _source 的特殊 lucene 字段中。

    当您使用 elasticsearch 搜索时,默认情况下会返回整个源字段,但您也可以要求特定字段。在这种情况下,elasticsearch 会检查这些特定字段是否存储在 lucene 中。如果是则将从lucene中检索内容,否则将从lucene中检索_source存储的字段,解析为json(拉解析)并提取那些特定的字段。在第一种情况下,它可能会快一点,但不一定。如果您的源非常大并且您只想加载几个字段,那么将它们配置为存储在 lucene 中可能会使加载过程更快;另一方面,如果您的_source 不是那么大并且您想要加载许多字段,那么最好只加载一个存储字段(_source),这将导致单个磁盘查找,解析它等等。在大多数情况下,使用_source 字段就可以了。

    回答您的问题:倒排索引和 lucene 存储是两个完全不同的东西。仅当您决定存储一个字段(映射中的store:yes)时,您最终会在 lucene 中拥有相同数据的两个副本,因为 elasticsearch 将相同的内容保留在 json _source 中,但这没有任何意义与您正在索引或分析该字段的事实有关。

    【讨论】:

    • 谢谢。我在某种程度上理解了差异(尽管您澄清了一些事情,谢天谢地!),我的问题更多的是:如果我们要存储大量的短字符串(~ 80 个字符的字符串),我们都需要检索并执行精确匹配(通过使用“not_analyzed”分析它们),索引和存储字段的位置之间是否存在数据重复。看起来有,但正如你所解释的,它们的性质和用法有很大不同,所以这不是真正的重复。
    • 我们的大部分领域都有_sourcefalse
    • 好的,如果你有 _source false 你没有什么可担心的。这就像用相同的数据做两件不同的事情。两种数据结构(倒排索引和存储)完全不同,用途也不同。甚至没有办法避免这种情况,除非您只想从 lucene/elasticsearch 中获取匹配文档的文档 ID 并使用其他一些外部存储。
    • 只是对出色答案的小评论;使用 _source 字段会比存储 10 个不同的字段并请求它们更快,因为这意味着从磁盘中获取比仅获取 _source 更多。作为黄金法则;更喜欢 _source 来存储,除非有很好的理由不存储,例如一个非常大的 _source。
    • @javanna 这是我曾经从 Shay 的笔下读到的。好的,我又找到了:elasticsearch-users.115913.n3.nabble.com/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多