【问题标题】:analyzed vs not_analyzed: storage size分析与未分析:存储大小
【发布时间】:2018-11-29 22:07:59
【问题描述】:

我最近开始使用 ElasticSearch 2。由于我不理解映射中的 analyzednot_analyzed,因此 not_analyzed 在存储方面应该更好(https://www.elastic.co/blog/elasticsearch-storage-the-true-story-2.0https://www.elastic.co/blog/elasticsearch-storage-the-true-story) . 出于测试目的,我创建了一些将所有 String 字段都作为分析的索引(默认情况下),然后我创建了一些其他索引,所有字段都为 not_analyzed,当我检查索引的大小并看到索引与未分析的字符串增加了 40% 更大!!我在每个索引(35000 个文档)中插入了相同的文档。

知道为什么会这样吗?我的文档是简单的 JSON 文档。我在每个文档中有 60 个字符串字段,我想设置为 not_analyzed,我尝试将每个字段设置为未分析并创建动态模板。

我编辑添加映射,虽然我认为它没有什么特别之处:

    {
        "mappings": {
            "my_type" : {
                          "_ttl" : { "enabled" : true, "default" : "7d" },
                          "properties" : {
                                "field1" : {
                                    "properties" : {
                                        "field2" : {
                                            "type" : "string", "index" : "not_analyzed"
                                        }
                                        more not_analyzed String fields here
                                  ...
                              ...
                          ...
}

【问题讨论】:

  • 你能发布完整的映射定义吗?可能还有其他属性归因于此。例如,您是否设置了 store 属性。在某些情况下,可能会导致将重复数据添加到索引中。
  • 我添加了部分映射,剩下的只是更多的字段。我没有添加商店属性或其他任何东西。
  • 为了详细说明我们的两个答案,not_analyzed 的主要用途是用于聚合之类的事情。如果您有(例如)一个类别字段,您希望能够按该类别进行排序/过滤,但可能不关心是否有人真的可以搜索它。这意味着您希望它不被分析为一组标记进行搜索,而是保存为输入的原始字符串。

标签: elasticsearch


【解决方案1】:

not_analyzed 字段仍被编入索引。他们只是没有事先应用任何转换(“分析” - 在 Lucene 用语中)。

举个例子:

(Doc 1)“敏捷的棕色狐狸跳过了懒惰的狗”

(Doc 2)“像狐狸一样懒惰”


  1. 标准分析器创建的简化发布列表(analyzed 字符串字段的默认值 - 标记化、小写、停用词已删除):
"brown": [1]  
"dog": [1]  
"fox": [1,2]  
"jumped": [1]  
"lazy": [1,2]  
"over": [1] 
"quick": [1]

30 个字符的字符串数据


  1. "index": "not_analyzed" 创建的简化发布列表:
"The quick brown fox jumped over the lazy dog": [1]  
"Lazy like the fox": [2] 

62 个字符的字符串数据


分析导致输入被标记化和规范化,以便能够使用术语查找文档。

但结果,文本单元被缩减为规范化术语(与not_analyzed 的整个字段相比),以及所有文档中的所有冗余(规范化)术语 被折叠成一个单个逻辑列表,为您节省了通常会被重复的术语和停用词占用的所有空间。

【讨论】:

  • 感谢您深入了解分析/原始数据集的外观。我不确定我的答案:)
  • 我知道它是如何工作的,我也想过这个问题,但我对官方文档中总是显示 not_analyzed 在两个文档中都比analyzed 更好的事实感到困惑。你的解释让我觉得实际上是相反的,分析通常会节省更多空间。
  • 分析是一个通用的总称,您可以在其中填充任意数量的文本转换。在我给出的示例中,分析导致存储的文本净减少。但是在很多情况下,输入文本的分析量可能会大得多(ngrams、shingles、同义词扩展、语音扩展、单词分隔符扩展)。这实际上取决于您在分析步骤中所做的工作。从 Peter Kim 的博客文章中并不清楚,正在发生什么样的转变以及在哪些领域......或者最终结果应该是扩展还是缩减。
  • 此外,分析生成/添加到其他数据结构,例如术语位置/偏移量,跳过列表等......否则就不必存在。您真的可以全面比较 analyzednot_analyzed 的索引大小。另外值得一提的是,如果您根本不需要匹配字段,您可以使用index: no 代替not_analyzed 将数据完全排除在发布列表之外。
  • 好的。明白了。感谢您的回答!
【解决方案2】:

the documentation 看来,not_analyzed 使该字段充当“关键字”而不是“全文”字段——让我们比较这两者!

全文

对这些字段进行分析,也就是说,它们在被索引之前通过分析器将字符串转换为单个术语的列表。

关键字

关键字字段未分析。而是将确切的字符串值作为单个项添加到索引中。

我并不感到惊讶,将整个字符串存储为一个术语,而不是将其分解为一个术语列表,并不一定会转化为节省空间。老实说,这可能取决于索引的分析器和被索引的字符串。


附带说明一下,我刚刚重新索引了大约一百万份生产数据文档,并将索引磁盘空间使用量减少了约 95%。我所做的主要区别是修改源中实际保存的内容(AKA 存储)。我们为搜索的 PDF 编制了索引,但不需要返回它们,这样我们就不用以两种不同的方式(分析的和原始的)保存这些信息。不过,这里有一些very real downsides,所以要小心!

【讨论】:

  • 这大大减少了磁盘空间!
  • 我很震惊。我预计只有大约 15-30%,但我认为这是有道理的,因为我们在大约百万行中存储了大约 150GB 的 PDF。
【解决方案3】:

文档1{ "name":"我的名字是 mayank kumar" }

Doc2.{ “名称”:“mayank” }

Doc3.{ “名称”:“玛雅克” }

我们有 3 个文件。

因此,如果字段 'name' 是 'not_analyzed' 并且我们搜索 'mayank' 只会返回第二个文档。如果我们搜索 'Mayank' 只会返回第三个文档。

如果字段“name”被分析器“小写分析器”“分析”(仅作为示例)。我们搜索“mayank”,将返回所有 3 个文档。 如果我们搜索“kumar”,将返回第一个文档。这是因为在第一个文档中,字段值被标记为“my”“name”“is”“mayank”“kumar”

'not_analyzed' 基本上用于'全文'搜索(主要用于通配符匹配除外)。磁盘空间更少。索引期间花费的时间更少。

'analyzed' 主要用于匹配文档。更多磁盘空间(如果分析字段很大)。在索引期间花费更多时间。(由于分析字段更多字段)

【讨论】:

    猜你喜欢
    • 2014-12-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2016-05-07
    相关资源
    最近更新 更多