原英文版地址: https://www.elastic.co/guide/en/elasticsearch/reference/7.7/flattened.html, 原文档版权归 www.elastic.co 所有
本地英文版地址: ../en/flattened.html

flattened(扁平)数据类型

默认情况下,对象中的每个子字段都被单独映射和索引。 如果事先不知道子字段的名称或类型,则它们会被动态映射

flattened类型提供了另一种方法,将整个对象映射为单个字段。 给定一个对象,flattened映射将解析出它的叶子值(leave value),并将它们作为关键字索引到一个字段中。 然后,可以通过简单的查询和聚合来搜索对象的内容。

这种数据类型对于索引具有大量或未知数量的唯一键的对象非常有用。 对于整个JSON对象,只创建一个字段映射,这有助于防止映射爆炸,因为有太多不同的字段映射。

另一方面,扁平化的对象字段在搜索功能方面有所取舍。 只允许基本查询,不支持数值范围查询或高亮。 有关限制的更多信息,请参见支持的操作部分。

flattened映射类型应用于索引所有文档内容,因为它将所有值视为keyword类型,并且不提供全文搜索功能。 默认的方法是每个子字段在映射中都有自己的入口,这种方法在大多数情况下都能很好地工作。

可以按如下方式创建一个 flattened 对象字段:

PUT bug_reports
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "labels": {
        "type": "flattened"
      }
    }
  }
}

POST bug_reports/_doc/1
{
  "title": "Results are not sorted correctly.",
  "labels": {
    "priority": "urgent",
    "release": ["v1.2.5", "v1.3.0"],
    "timestamp": {
      "created": 1541458026,
      "closed": 1541457010
    }
  }
}

在编制索引的过程中,会为 JSON 对象中的每个叶子值创建 词元(token)。 这些值作为字符串值形式的 keyword 进行索引,不需要对数字或日期进行分析或特殊处理。

查询flattened字段的顶级键,会搜索对象中的所有叶子值:

POST bug_reports/_search
{
  "query": {
    "term": {"labels": "urgent"}
  }
}

要查询flattened对象中的特定键,可以使用对象点标记法:

POST bug_reports/_search
{
  "query": {
    "term": {"labels.release": "v1.3.0"}
  }
}

支持的操作

由于值的索引方式相似,flattened字段与keyword字段共享许多相同的映射和搜索功能。

目前,flattened 对象类型的字段可用于以下查询类型:

  • termtermsterms_set
  • prefix
  • range
  • matchmulti_match
  • query_stringsimple_query_string
  • exists

查询时,不能使用通配符引用字段的键,如在 { "term": {"labels.time*": 1541457010}}中。 请注意,包括range在内的所有查询都将这些值视为字符串 keyword 类型。 flattened字段不支持高亮。

可以对 flattened 对象字段进行排序,也可以执行简单的 keyword 式聚合,如terms。 与查询一样,没有对数值的特殊支持 - JSON对象中的所有值都被视为 keyword 类型。 这意味着排序时会按字典顺序进行值的比较。

当前无法存储 flattened 对象字段。 不能在映射中指定参数store

flattened 对象字段的参数

支持以下几个映射参数:

boost

映射字段级查询时的提升。接受浮点数,默认值为1.0

depth_limit

就嵌套内部对象而言,flattened 对象字段的最大允许深度。 如果 flattened 对象字段超过此限制,则会抛出错误。 默认值为 20。 注意,depth_limit可以通过映射设置 API 动态更新。

doc_values

该字段是否应该以列跨度(column-stride)的方式存储在磁盘上,以便以后用于排序、聚合或编写脚本?接受true (默认) 和 false

eager_global_ordinals

是否应该在刷新时加载全局序号? 接受truefalse(默认)。 对于常用于 terms 聚合的字段,启用此功能是个好主意。

ignore_above

超过此限制的叶子值将不会被索引。 默认情况下,没有限制,所有值都将被索引。 请注意,此限制适用于 flattened 对象字段内的叶子值,而不是整个字段的长度。

index

确定字段是否应可搜索。接受true (默认) 和 false

index_options

出于评分目的,应该在索引中存储什么信息。 默认为docs,但也可以设置为freqs,以便在计算分数时考虑词项的频率。

null_value

替换 flattened 对象字段中任何显式null值的字符串值。 默认为null,这意味着 null 字段被视为缺失。

similarity

应该使用哪种评分或相似度算法。默认为BM25

split_queries_on_whitespace

为该字段构建查询时,全文查询是否应该使用"空白"拆分输入。 接受truefalse (默认)。