35

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

我的问题:

  • 如果一个字符串字段同时存储为not_analyzedand store:yes,是否会有重复存储的字符串?

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

4

1 回答 1

91

您在 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 存储是两个完全不同的东西。仅当您决定存储一个字段(在映射中)时,您最终在 lucene 中拥有相同数据的两个副本store:yes,因为 elasticsearch 将相同的内容保留在 json_source中,但这与您的事实没有任何关系'正在索引或分析该字段。

于 2013-03-10T09:18:39.420 回答