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