ElasticSearch深入解析(九):Object、Nested、Flattened类型

文章目录

      • 一、Object 类型:默认的嵌套对象处理方式
        • 核心原理
        • 典型场景
        • 关键限制
      • 二、Nested 类型:解决嵌套数组的关联查询
        • 核心原理
        • 典型场景
        • 使用示例
        • 注意事项
      • 三、Join 类型:跨文档的父子关联
        • 核心原理
        • 典型场景
        • 使用示例
        • 注意事项
      • 四、Flattened 类型:动态嵌套对象的轻量化处理
        • 核心原理
        • 典型场景
        • 使用示例
        • 注意事项
      • 五、类型对比与选择建议

Elasticsearch 作为面向文档的搜索引擎,对嵌套数据的处理有多种方式,不同类型适用于不同的业务场景。

一、Object 类型:默认的嵌套对象处理方式

核心原理

Elasticsearch 中,JSON 文档的嵌套对象(如 {"user": {"name": "张三", "age": 25}})会被默认映射为 Object 类型。其底层通过 字段扁平化 实现索引:将嵌套对象的字段展开为 父字段.子字段 的形式(如 user.nameuser.age),存储为独立的字段。

典型场景

适用于 简单嵌套对象,且不需要对嵌套对象内部字段进行 关联查询 的场景。例如:

{"article": {"title": "ES 数据类型指南","author": { "name": "李四", "email": "lisi@example.com" }}
}

此时 author 是一个简单对象,若只需查询 author.nameauthor.email 的独立值(不关心是否属于同一作者),Object 类型足够。

关键限制

当嵌套对象是 数组 时(如一个用户有多个地址),Object 类型会 丢失对象内部字段的关联。例如:

{"user": "张三","addresses": [{"city": "北京", "zip": "100000"},{"city": "上海", "zip": "200000"}]
}

Elasticsearch 会将 addresses.city 存储为 ["北京", "上海"]addresses.zip 存储为 ["100000", "200000"]。若执行查询 city=北京 AND zip=200000,会错误匹配到这条文档(因为字段被扁平化,不关心“北京”和“200000”是否属于同一个地址对象)。

二、Nested 类型:解决嵌套数组的关联查询

核心原理

Nested 类型是 Object 类型的扩展,专门用于处理 嵌套对象数组。它将数组中的每个对象 独立索引为一个“子文档”,保留对象内部字段的关联关系。查询时需使用 nested 查询,确保只匹配同一嵌套对象内的字段。

典型场景

适用于 一对多关联 且需要对嵌套对象内部字段进行 组合查询 的场景。例如:

  • 订单的多个商品(需查询“购买了苹果手机且数量>2的订单”);
  • 用户的多个地址(需查询“城市为北京且邮编为100000的地址”)。
使用示例

映射定义

PUT /my_index
{"mappings": {"properties": {"user": {"type": "nested",  // 指定为 nested 类型"properties": {"name": {"type": "keyword"},"address": {"type": "nested",  // 支持多层嵌套"properties": {"city": {"type": "keyword"},"zip": {"type": "keyword"}}}}}}}
}

查询示例(匹配同一地址内的城市和邮编):

GET /my_index/_search
{"query": {"nested": {"path": "user.address",  // 指定嵌套路径"query": {"bool": {"must": [{"term": {"user.address.city": "北京"}},{"term": {"user.address.zip": "100000"}}]}}}}
}
注意事项
  • 性能与存储:每个嵌套对象独立索引,会增加索引体积(约为普通 Object 类型的 1.5~3 倍);
  • 嵌套层级:支持多层嵌套(如 user.address.street),但深度建议不超过 5 层(过深会影响查询性能);
  • 更新限制:修改嵌套对象的任意字段需重新索引整个父文档(类似关系型数据库的级联更新)。

三、Join 类型:跨文档的父子关联

核心原理

Join 类型允许在 同一索引 中建立父子文档关系(如父文档是“用户”,子文档是“用户的订单”)。通过 _parent 字段关联父子文档,父文档和子文档需存储在 同一分片 上(通过父文档的 _id 哈希到分片)。

典型场景

适用于 跨文档的一对多关联,且父子文档需要 独立更新 的场景。例如:

  • 论坛的“板块(父)- 帖子(子)”;
  • 企业的“部门(父)- 员工(子)”。
使用示例

映射定义

PUT /my_index
{"mappings": {"properties": {"join_field": { "type": "join","relations": {"department": "employee"  // 父类型: "department",子类型: "employee"}}}}
}

创建父文档(部门)

PUT /my_index/_doc/1
{"name": "技术部","join_field": { "name": "department" }  // 标记为父类型
}

创建子文档(员工)

PUT /my_index/_doc/2?routing=1  // 必须与父文档同分片(routing=父文档ID)
{"name": "张三","join_field": { "name": "employee", "parent": "1"  // 关联父文档ID}
}

查询示例(查询技术部的所有员工):

GET /my_index/_search
{"query": {"has_parent": {"parent_type": "department","query": { "term": { "name": "技术部" } }}}
}
注意事项
  • 性能瓶颈:父子查询需要跨文档关联(类似关系型数据库的 JOIN),性能低于 Nested 类型(Nested 是单文档内的关联);
  • 分片限制:父文档和子文档必须同分片,若父文档分布不均可能导致分片数据倾斜;
  • 适用场景:仅当父子文档需要 独立更新(如父文档修改不影响子文档)时使用,否则优先选择 Nested 类型。

四、Flattened 类型:动态嵌套对象的轻量化处理

核心原理

Flattened 类型用于将 复杂的嵌套 JSON 对象(如动态结构的元数据)展平为单个字段。所有嵌套的键会被合并为 点分隔的字符串(如 {"a": {"b": "c"}} 会被展平为 a.b: c),并索引为 keyword 类型(支持精确匹配)。

典型场景

适用于 动态或未知结构的嵌套对象,例如:

  • 日志中的 tags 字段(可能包含任意层级的键值对);
  • 商品的扩展属性(如不同品类的额外信息)。
使用示例

映射定义

PUT /my_index
{"mappings": {"properties": {"metadata": {"type": "flattened"  // 指定为 flattened 类型}}}
}

文档示例

PUT /my_index/_doc/1
{"metadata": {"user": {"name": "张三","age": 25},"device": "iPhone 15"}
}

此时 metadata 会被展平为 metadata.user.name: "张三"metadata.user.age: "25"metadata.device: "iPhone 15" 等字段。

查询示例(精确匹配展平后的路径):

GET /my_index/_search
{"query": {"term": { "metadata.user.name": "张三" }  // 直接使用展平后的字段名}
}
注意事项
  • 字段限制:展平后的字段数量默认最多 1000 个(可通过 max_flattened_fields 参数调整);
  • 查询能力:仅支持精确匹配(term)或前缀匹配(prefix),无法进行范围查询(如 age>20);
  • 适用场景:优先用于 不需要复杂查询 的动态嵌套对象(如日志元数据),避免因动态映射导致字段爆炸。

五、类型对比与选择建议

类型核心特点适用场景性能与限制
Object扁平化存储,丢失嵌套对象关联简单嵌套对象,无需关联查询轻量,无法处理嵌套数组的关联查询
Nested独立索引嵌套对象,保留关联一对多嵌套数组,需关联查询索引体积大,更新成本高
Join跨文档父子关联父子需独立更新,跨文档查询查询性能差,分片限制严格
Flattened展平动态嵌套对象,简化索引动态/未知结构的嵌套对象,轻查询仅支持精确匹配,字段数量受限

选择建议

  1. 优先使用 Nested 类型 处理嵌套数组的关联查询(如订单-商品);
  2. 仅当父子需独立更新时使用 Join 类型(如部门-员工);
  3. 动态或未知结构的嵌套对象用 Flattened 类型(如日志元数据);
  4. 简单嵌套对象且无需关联查询时,使用默认的 Object 类型

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904289.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

36、C#中的⽅法声明参数关键字params,ref,out的意义及⽤法

在C#中,params、ref 和 out 是方法声明中用于修饰参数的关键字,它们各自有不同的用途和语义。以下是它们的详细说明和用法: 1、 params 关键字 意义 params 允许方法接受可变数量的参数,这些参数会被编译为一个数组。适用于参数…

【大模型实战篇】华为信创环境采用vllm部署QwQ-32B模型

1. 背景 本文分享在华为昇腾机器上部署QwQ-32B模型的实践。 首先华为自己是提供了一套在信创机器(NPU)上部署模型的方案【1】,但是部署之后,测试发现会有输出截断的现象。QwQ-32B本身是支持128k的最大上下文长度,定位…

前端面经-VUE3篇(二)--vue3基础知识(二)计算属性(computed)、监听属性(Watch)

一、计算属性(computed) 计算属性(Computed Properties)是 Vue 中一种特殊的响应式数据,它能基于已有的响应式数据动态计算出新的数据。 计算属性有以下特性: 自动缓存:只有当它依赖的响应式数据发生变化时&#xff…

[预备知识] 5. 优化理论(一)

优化理论 梯度下降(Gradient Descent) 数学原理与可视化 梯度下降是优化领域的基石算法,其核心思想是沿负梯度方向迭代更新参数。数学表达式为: θ t 1 θ t − α ∇ θ J ( θ t ) \theta_{t1} \theta_t - \alpha \nabla…

大模型微调Fine-tuning:从概念到实践的全面解析

目录 引言 一、什么是大模型微调? 1.1 预训练与微调的区别 1.2 微调的技术演进 二、为什么需要微调? 2.1 解决大模型的固有局限 2.2 微调的优势 三、主流微调方法 3.1 全参数微调 3.2 参数高效微调(PEFT) 四、微调实践指…

Docker 使用下 (二)

Docker 使用下 (二) 文章目录 Docker 使用下 (二)前言一、初识Docker1.1 、Docker概述1.2 、Docker的历史1.3 、Docker解决了什么问题1.4 、Docker 的优点1.5 、Docker的架构图 二、镜像三、容器四、数据卷4.1、数据卷的概念4.2 、…

洛谷P12238 [蓝桥杯 2023 国 Java A] 单词分类

[Problem Discription] \color{blue}{\texttt{[Problem Discription]}} [Problem Discription] Copy from luogu. [Analysis] \color{blue}{\texttt{[Analysis]}} [Analysis] 既然都是字符串前缀的问题了,那当然首先就应该想到 Trie \text{Trie} Trie 树。 我们可…

pta作业中有启发性的程序题

1 【知识点】&#xff1a;多态 函数接口定义&#xff1a; 以Student为基类&#xff0c;构建GroupA, GroupB和GroupC三个类 裁判测试程序样例&#xff1a; #include<iostream> #include <string> using namespace std;/* 请在这里填写答案 */int main() {const …

Scrapy框架之CrawlSpider爬虫 实战 详解

CrawlSpider 是 Scrapy 框架中一个非常实用的爬虫基类&#xff0c;它继承自 Spider 类&#xff0c;主要用于实现基于规则的网页爬取。相较于普通的 Spider 类&#xff0c;CrawlSpider 可以根据预定义的规则自动跟进页面中的链接&#xff0c;从而实现更高效、更灵活的爬取。 Scr…

Glide 如何加载远程 Base64 图片

最近有个需求&#xff0c;后端给出的图片地址并不是正常的 URL&#xff0c;而且需要一个接口去请求&#xff0c;但是返回的是 base64 数据流。这里不关心为啥要这么多&#xff0c;原因有很多&#xff0c;可能是系统的问题&#xff0c;也可能是能力问题。当然作为我们 Android 程…

004-nlohmann/json 快速认识-C++开源库108杰

了解 nlohmann/json 的特点&#xff1b;理解编程中 “数据战场”划分的概念&#xff1b;迅速上手多种方式构建一个JSON对象&#xff1b; 1 特点与安装 nlohmann/json 是一个在 github 长期霸占 “JSON” 热搜版第1的CJSON处理库。它的最大优点是与 C 标准库的容器数据&#xf…

#基础Machine Learning 算法(上)

机器学习算法的分类 机器学习算法大致可以分为三类&#xff1a; 监督学习算法 (Supervised Algorithms&#xff09;:在监督学习训练过程中&#xff0c;可以由训练数据集学到或建立一个模式&#xff08;函数 / learning model&#xff09;&#xff0c;并依此模式推测新的实例。…

正弦波、方波、三角波和锯齿波信号发生器——Multisim电路仿真

目录 Multisim使用教程说明链接 一、正弦波信号发生电路 1.1正弦波发生电路 电路组成 工作原理 振荡频率 1.2 正弦波发生电路仿真分析 工程文件链接 二、方波信号发生电路 2.1 方波发生电路可调频率 工作原理 详细过程 2.2 方波发生电路可调频率/可调占空比 调节占空比 方波产生…

【AND-OR-~OR锁存器设计】2022-8-31

缘由锁存器11111111111-硬件开发-CSDN问答 重置1&#xff0c;不论输入什么&#xff0c;输出都为0&#xff1b; 重置0&#xff0c;输入1就锁住1 此时输入再次变为0&#xff0c;输出不变&#xff0c;为锁住。

力扣-字符串-468 检查ip

思路 考察字符串的使用&#xff0c;还有对所有边界条件的检查 spilt&#xff08;“\.”&#xff09;&#xff0c;toCharArray&#xff0c;Integer.parseInt() 代码 class Solution {boolean checkIpv4Segment(String str){if(str.length() 0 || str.length() > 4) retur…

BC8 十六进制转十进制

题目&#xff1a;BC8 十六进制转十进制 描述 BoBo写了一个十六进制整数ABCDEF&#xff0c;他问KiKi对应的十进制整数是多少。 输入描述&#xff1a; 无 输出描述&#xff1a; 十六进制整数ABCDEF对应的十进制整数&#xff0c;所占域宽为15。 备注&#xff1a; printf可以使用…

ARM子程序和栈

微处理器中的栈由栈指针指向存储器中的栈顶来实现&#xff0c;当数据项入栈时&#xff0c;栈 指针向上移动&#xff0c;当数据项出栈时&#xff0c;栈指针向下移动。 实现栈时需要做出两个决定&#xff1a;一是当数据项进栈时是向低位地址方向向上生 长&#xff08;图a和图b&a…

jwt身份验证和基本的利用方式

前言 &#xff1a; 什么是jwt&#xff08;json web token&#xff09;&#xff1f; 看看英文单词的意思就是 json形式的token 他的基本的特征 &#xff1a; 类似于这样的 他有2个点 分割 解码的时候会有三个部分 头部 payload 对称密钥 这个就是对称加密 头部&am…

n8n工作流自动化平台的实操:利用本地嵌入模型,完成文件内容的向量化及入库

1.成果展示 1.1n8n的工作流 牵涉节点&#xff1a;FTP、Code、Milvus Vector Store、Embeddings OpenAI、Default Data Loader、Recursive Character Text Splitter 12.向量库的结果 2.实操过程 2.1发布本地嵌入模型服务 将bge-m3嵌入模型&#xff0c;发布成满足open api接口…

MATLAB人工大猩猩部队GTO优化CNN-LSTM多变量时间序列预测

本博客来源于CSDN机器鱼&#xff0c;未同意任何人转载。 更多内容&#xff0c;欢迎点击本专栏目录&#xff0c;查看更多内容。 目录 0 引言 1 数据准备 2 CNN-LSTM模型搭建 3 GTO超参数优化 3.1 GTO函数极值寻优 3.2 GTO优化CNN-LSTM超参数 3.3 主程序 4 结语 0 引言…