elsaticsearch 中的源过滤、存储字段和文档值之间有什么区别?

eve*_*992 2 elasticsearch

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

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


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


默认情况下,所有支持文档值的字段都启用它们。

实施例1

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

  1. 带源过滤
GET /_search
{ _source: "obj.title", ... }
Run Code Online (Sandbox Code Playgroud)
  1. 具有存储字段
GET /_search
{ _source: false, stored_fields: ["title"], ... }
Run Code Online (Sandbox Code Playgroud)
  1. 带有文档值
GET /_search
{_source: false, stored_fields: "_none_", docvalue_fields: "title", ... }
Run Code Online (Sandbox Code Playgroud)

可以,然后呢

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

Val*_*Val 6

源过滤请求是否会从磁盘读取完整的_source、标题和内容,然后应用过滤器并仅返回标题,或者elasticsearch只会从磁盘读取标题?

您发送到 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"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

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