Elasticsearch 索引父子关系(索引父子关系)
#Elasticsearch允许给文档建立父子关系,这篇博客介绍文档的父子关系是如何映射的(Parent-Child Mapping)、如何索引父子文档(Indexing Parents and Children)、如何通过子文档查询父文档
(Finding Parents by Their Children)、如何通过父文档查询子文档(Finding Children by Their Parents)。
一、父子文档的mapping
建立文档的父子关系最重要的一步是在创建索引的时候在mapping中声明哪个是父文档哪个是子文档。官网文档给了一个公司在很多城市的分支(branch)和每个分支有相关员工(employee)的例子,如果想把员工和他们工作的分公司关联起来,我们需要告诉Elasticsearch文档之间的父子关系,这里employee是child type,branch是parent type,在mapping中声明:
curl -XPUT "http://192.168.0.224:9200/company" -d '
{
"mappings": {
"branch": {},
"employee": {
"_parent": {
"type": "branch"
}
}
}
}
'
这样我们创建了一个索引,并制定了2个type和它们之间的父子关系.
二、父子文档的索引
2.1索引父文档
索引父文档和索引一般的文档没有任何区别。
准备几条公司的数据,存在company.json文件中:
{ "index": { "_id": "london" }}
{ "name": "London Westminster", "city": "London", "country": "UK" }
{ "index": { "_id": "liverpool" }}
{ "name": "Liverpool Central", "city": "Liverpool", "country": "UK" }
{ "index": { "_id": "paris" }}
{ "name": "Champs Élysées", "city": "Paris", "country": "France" }
使用Bulk端点批量导入:
curl -XPOST "http://192.168.0.224:9200/company/branch/_bulk?pretty" --data-binary @company.json
2.2索引子文档
索引子文档需要制定子文档的父ID,给子文档的每条文档设置parent属性的value为父文档id即可:
curl -XPUT "http://192.168.0.224:9200/company/employee/1?parent=london&pretty" -d '
{
"name": "Alice Smith",
"dob": "1970-10-24",
"hobby": "hiking"
}
'
上面的操作我们新增了一条数据,/company/employee/1的父文档为/company/branch/london。
同样可以批量索引子文档,把employee数据存入json文件中:
{ "index": { "_id": 2, "parent": "london" }}
{ "name": "Mark Thomas", "dob": "1982-05-16", "hobby": "diving" }
{ "index": { "_id": 3, "parent": "liverpool" }}
{ "name": "Barry Smith", "dob": "1979-04-01", "hobby": "hiking" }
{ "index": { "_id": 4, "parent": "paris" }}
{ "name": "Adrien Grand", "dob": "1987-05-11", "hobby": "horses" }
执行bulk命令:
curl -XPOST "http://192.168.0.224:9200/company/employee/_bulk?pretty" --data-binary @employee.json
三、通过子文档查询父文档
搜索含有1980年以后出生的employee的branch:
curl -XGET "http://192.168.0.224:9200/company/branch/_search?pretty" -d '
{
"query": {
"has_child": {
"type": "employee",
"query": {
"range": {
"dob": {
"gte": "1980-01-01"
}
}
}
}
}
}
'
{
"took" : 19,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [ {
"_index" : "company",
"_type" : "branch",
"_id" : "paris",
"_score" : 1.0,
"_source" : {
"name" : "Champs Élysées",
"city" : "Paris",
"country" : "France"
}
}, {
"_index" : "company",
"_type" : "branch",
"_id" : "london",
"_score" : 1.0,
"_source" : {
"name" : "London Westminster",
"city" : "London",
"country" : "UK"
}
} ]
}
}
查询name中含有“Alice Smith”的branch:
curl -XGET "http://192.168.0.224:9200/company/branch/_search?pretty" -d '
{
"query": {
"has_child": {
"type": "employee",
"score_mode": "max",
"query": {
"match": {
"name": "Alice Smith"
}
}
}
}
}'
{
"took" : 20,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.2422675,
"hits" : [ {
"_index" : "company",
"_type" : "branch",
"_id" : "london",
"_score" : 1.2422675,
"_source" : {
"name" : "London Westminster",
"city" : "London",
"country" : "UK"
}
}, {
"_index" : "company",
"_type" : "branch",
"_id" : "liverpool",
"_score" : 0.30617762,
"_source" : {
"name" : "Liverpool Central",
"city" : "Liverpool",
"country" : "UK"
}
} ]
}
}
搜索最少含有2个employee的branch:
curl -XGET "http://192.168.0.224:9200/company/branch/_search?pretty" -d '{
"query": {
"has_child": {
"type": "employee",
"min_children": 2,
"query": {
"match_all": {}
}
}
}
}
'
{
"took" : 17,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [ {
"_index" : "company",
"_type" : "branch",
"_id" : "london",
"_score" : 1.0,
"_source" : {
"name" : "London Westminster",
"city" : "London",
"country" : "UK"
}
} ]
}
}
四、通过父文档查询子文档
搜搜工作在UK的employee:
curl -XGET "http://192.168.0.224:9200/company/employee/_search?pretty" -d '{
"query": {
"has_parent": {
"type": "branch",
"query": {
"match": {
"country": "UK"
}
}
}
}
}'
{
"took" : 15,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [ {
"_index" : "company",
"_type" : "employee",
"_id" : "3",
"_score" : 1.0,
"_parent" : "liverpool",
"_routing" : "liverpool",
"_source" : {
"name" : "Barry Smith",
"dob" : "1979-04-01",
"hobby" : "hiking"
}
}, {
"_index" : "company",
"_type" : "employee",
"_id" : "1",
"_score" : 1.0,
"_parent" : "london",
"_routing" : "london",
"_source" : {
"name" : "Alice Smith",
"dob" : "1970-10-24",
"hobby" : "hiking"
}
}, {
"_index" : "company",
"_type" : "employee",
"_id" : "2",
"_score" : 1.0,
"_parent" : "london",
"_routing" : "london",
"_source" : {
"name" : "Mark Thomas",
"dob" : "1982-05-16",
"hobby" : "diving"
}
} ]
}
}
下一篇: Linux 进程间通信 IPC
推荐阅读
-
Elasticsearch 一书在手--索引
-
在 Elasticsearch 中更改索引 - 2.重新索引数据
-
Elasticsearch:一款强大的分布式搜索引擎
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
深入了解 Elasticsearch 8.X 索引模板:从传统模板到可组合模板的全面指南
-
elasticSearch的索引库文档的增删改查
-
腾讯云 Elasticsearch 集群运维常用命令详解三(索引篇)
-
ElasticSearch 最完整、最详细的使用教程:入门、索引管理、映射详情
-
Elasticsearch 索引父子关系(索引父子关系)
-
使用阿里云试用 Elasticsearch 学习:1.7 基本入门 - 索引管理