2

我已经阅读了有关源过滤存储字段文档值的文档。

在某些情况下,存储字段是有意义的。例如,如果您有一个包含标题、日期和非常大的内容字段的文档,您可能只想检索标题和日期,而不必从大的 _source 字段中提取这些字段


stored_fields 参数是关于在映射中显式标记为存储的字段,默认情况下是关闭的,通常不推荐使用。改为使用源过滤来选择要返回的原始源文档的子集。


所有支持 doc 值的字段都默认启用它们。

示例 1

我有title(短字符串)和content(> 1MB)的文档。我想搜索匹配的标题,并返回标题。

  1. 使用源过滤
GET /_search
{ _source: "obj.title", ... }
  1. 使用存储字段
GET /_search
{ _source: false, stored_fields: ["title"], ... }
  1. 带有文档值
GET /_search
{_source: false, stored_fields: "_none_", docvalue_fields: "title", ... }

可以,然后呢

  • 源过滤请求会_source从磁盘读取完整的标题和内容,然后应用过滤器并仅返回标题,还是弹性搜索仅从磁盘读取标题?
  • 源过滤请求会使用文档值吗?
  • 存储字段是存储分析的标记还是原始值?
  • 存储的字段或文档值是否比 _source 效率更高或更低?
4

1 回答 1

5

源过滤请求会从磁盘读取完整的_source、标题和内容,然后应用过滤器并仅返回标题,还是弹性搜索仅从磁盘读取标题?

您发送给 Elasticsearch 索引的文档将存储在一个名为_source(默认情况下)的字段中。因此,这意味着如果您的文档包含大量数据(例如在content您的情况下的字段中),则完整内容将存储在该_source字段中。使用源过滤时,首先必须从_source字段中检索整个源文档,然后只title返回该字段。您正在浪费空间,因为该字段没有真正发生任何事情content,因为您正在搜索title并仅返回title值。

在你的情况下,你最好不要存储_source文档,而只存储title字段(但它也有一些缺点,所以在你做之前阅读这个),基本上是这样的:

PUT index
{
  "mappings": {
    "_source": {
      "enabled": false
    },
    "properties": {
      "title": {
        "type": "text",
        "store": true 
      },
      "content": {
        "type": "text"
      }
    }
  }
}

源过滤请求是否会使用文档值?

默认情况下,所有字段都启用 doc-values,但分析的文本字段除外。如果您使用_source过滤,则不使用文档值,如上所述,_source检索该字段并过滤您指定的字段。

存储字段是存储分析的标记还是原始值?

存储字段存储_source文档中存在的确切值

存储的字段或文档值是否比 _source 效率更高或更低?

doc_values 是一个不同的野兽,它更多地是一种优化,以一种方式存储非分析字段的标记,以便于对这些值进行排序、过滤和聚合。

如果您不想存储完整的源代码而只想存储几个重要字段(如上所述),则存储字段(默认为 false)也是一种优化。_source字段本身是包含整个文档的存储字段。

于 2019-09-16T20:00:07.890 回答