假设我在映射中有一个字符串字段指定为not_analyzed
。如果我然后将"store":"yes"
添加到映射中,ElasticSearch会复制存储吗?我对not_analyzed
字段的理解是,它们不是通过分析器运行,按索引,但客户端能够匹配它。因此,如果某个字段同时为not_analyzed
和store:yes
,则可能会导致ElasticSearch保留该字符串的两个副本。
我的问题:
not_analyzed
和store:yes
,那么字符串是否会存在重复存储?我希望这很清楚。谢谢!
答案 0 :(得分:91)
你在lucene中混合了索引字段和存储字段的概念,即弹性搜索建立在其上的库。
当字段进入倒排索引时,该字段被索引,lucene用于提供其强大而快速的全文搜索功能的数据结构。如果要搜索字段,则必须对其进行索引。索引字段时,您可以决定是否要按原样对其进行索引,或者您要对其进行分析,这意味着决定应用于它的标记生成器,这将生成标记(单词)列表和标记列表可以修改生成的令牌的过滤器(甚至添加或删除一些)。索引字段的方式会影响您搜索字段的方式。如果您索引某个字段但不对其进行分析,并且其文本由多个单词组成,那么您将能够找到该文档,仅搜索包含空格的确切特定文本。
当您希望能够检索字段时,会存储该字段。让我们说Lucene也提供了某种存储,它与倒排索引本身没有任何关系。 当您使用lucene进行搜索时,您将获得匹配的文档ID列表。然后,您可以从其存储的字段中检索一些文本,这就是您真正显示为搜索结果的内容。如果你没有存储一个字段,你就永远无法从lucene中获取它(但对于弹性搜索来说这不是真的,我将在下面解释)。
您可以拥有您只想搜索的字段,并且永远不会显示:已编入索引且未存储(默认为lucene)。
您可以拥有要搜索的字段并检索:索引和存储
您可以拥有不想搜索的字段,但确实需要检索以显示它们。
因此,这两个数据结构彼此无关。如果您在lucene中索引并存储字段,则其内容将不会以相同的形式出现两次。当您将它们发送到lucene时,存储的字段按原样存储,而索引字段可能会被分析并且将成为反向索引的一部分,这是其他的东西。存储的字段用于检索特定文档(通过lucene文档id),而索引字段用于搜索,在这样的结构中,字面上反转文本,其结果是每个术语作为键,以及文档列表包含它的ID(帖子列表)。
当谈到弹性搜索时,事情会发生一些变化。如果未将映射中存储的字段配置为默认值(默认为store:no
),则默认情况下无论如何都可以检索该字段。发生这种情况是因为elasticsearch始终在lucene中存储您发送给它的整个源文档(除非您禁用此功能)在一个名为_source的特殊lucene字段中。
使用elasticsearch进行搜索时,默认情况下会返回整个源字段,但您也可以询问特定字段。在这种情况下会发生的事情是elasticsearch检查这些特定字段是否存储在lucene中。如果是,则将从lucene中检索内容,否则将从lucene检索_source
存储的字段,解析为json(拉解析)并且将提取这些特定字段。在第一种情况下,它可能会快一点,但不一定。如果您的源代码非常大并且您只想加载几个字段,那么将它们配置为存储在lucene中可能会使加载过程更快;另一方面,如果您的_source
不是那么大并且您想要加载许多字段,那么最好只加载一个存储的字段(_source
),这将导致单个磁盘在大多数使用_source
字段的情况下工作得很好。
回答你的问题:倒排索引和lucene存储是两个完全不同的东西。只有当您决定在映射中存储字段(store:yes
)时才会在lucene中拥有相同数据的两个副本,因为elasticsearch会在json _source
中保留相同的内容,但这并不是'与你正在索引或分析该字段的事实有任何关系。