Parent / Child
-
對(duì)象和 Nested 對(duì)象的局限性
- 每次更新坷随,需要重新索引整個(gè)對(duì)象(包括根對(duì)象和嵌套對(duì)象)
-
ES 提供了類似關(guān)系型數(shù)據(jù)庫(kù)中 Join 的實(shí)現(xiàn)疗韵。使? Join 數(shù)據(jù)類型實(shí)現(xiàn)岩瘦,可以通過(guò)維護(hù) Parent / Child 的關(guān)系缝裁,從?分離兩個(gè)對(duì)象
??檔和??檔是兩個(gè)獨(dú)?的?檔
更新??檔?需重新索引??檔铛只。??檔被添加跟磨,更新或者刪除也不會(huì)影響到??檔和其他的??檔
??關(guān)系
-
定義??關(guān)系的?個(gè)步驟
1.設(shè)置索引的 Mapping
2.索引??檔
3.索引??檔
4.按需查詢?檔
設(shè)置 Mapping
# 設(shè)定 Parent/Child Mapping
PUT my_blogs
{
"settings": {
"number_of_shards": 2
},
"mappings": {
"properties": {
"blog_comments_relation": {
"type": "join",
"relations": {
"blog": "comment"
}
},
"content": {
"type": "text"
},
"title": {
"type": "keyword"
}
}
}
}
索引??檔
#索引父文檔
PUT my_blogs/_doc/blog1
{
"title":"Learning Elasticsearch",
"content":"learning ELK @ geektime",
"blog_comments_relation":{
"name":"blog"
}
}
#索引父文檔
PUT my_blogs/_doc/blog2
{
"title":"Learning Hadoop",
"content":"learning Hadoop",
"blog_comments_relation":{
"name":"blog"
}
}
索引??檔
#索引子文檔
PUT my_blogs/_doc/comment1?routing=blog1
{
"comment":"I am learning ELK",
"username":"Jack",
"blog_comments_relation":{
"name":"comment",
"parent":"blog1"
}
}
#索引子文檔
PUT my_blogs/_doc/comment2?routing=blog2
{
"comment":"I like Hadoop!!!!!",
"username":"Jack",
"blog_comments_relation":{
"name":"comment",
"parent":"blog2"
}
}
#索引子文檔
PUT my_blogs/_doc/comment3?routing=blog2
{
"comment":"Hello Hadoop",
"username":"Bob",
"blog_comments_relation":{
"name":"comment",
"parent":"blog2"
}
}
-
??檔和??檔必須存在相同的分?上
- 確保查詢 join 的性能
-
當(dāng)指定??檔時(shí)候杆怕,必須指定它的??檔 Id
- 使? route 參數(shù)來(lái)保證族购,分配到相同的分?
Parent / Child 所?持的查詢
查詢所有?檔
Parent Id 查詢
Has Child 查詢
Has Parent 查詢
使? has_child 查詢
返回??檔
-
通過(guò)對(duì)??檔進(jìn)?查詢
返回具有相關(guān)??檔的??檔
???檔在相同的分?上,因此 Join 效率?
# Has Child 查詢,返回父文檔
POST my_blogs/_search
{
"query": {
"has_child": {
"type": "comment",
"query" : {
"match": {
"username" : "Jack"
}
}
}
}
}
使? has_parent 查詢
返回相關(guān)的??檔
通過(guò)對(duì)??檔進(jìn)?查詢
返回所有相關(guān)??檔
# Has Parent 查詢陵珍,返回相關(guān)的子文檔
POST my_blogs/_search
{
"query": {
"has_parent": {
"parent_type": "blog",
"query" : {
"match": {
"title" : "Learning Hadoop"
}
}
}
}
}
使? parent_id 查詢
返回所有相關(guān)??檔
通過(guò)對(duì)??檔 Id 進(jìn)?查詢
返回所有相關(guān)??檔
# Parent Id 查詢
POST my_blogs/_search
{
"query": {
"parent_id": {
"type": "comment",
"id": "blog2"
}
}
}
訪問(wèn)??檔
- 需指定??檔 routing 參數(shù)
#通過(guò)ID 寝杖,訪問(wèn)子文檔
GET my_blogs/_doc/comment3
res:(報(bào)錯(cuò))
{
"_index" : "my_blogs",
"_type" : "_doc",
"_id" : "comment3",
"found" : false
}
#通過(guò)ID和routing ,訪問(wèn)子文檔
GET my_blogs/_doc/comment3?routing=blog2
res:
{
"_index" : "my_blogs",
"_type" : "_doc",
"_id" : "comment3",
"_version" : 1,
"_seq_no" : 4,
"_primary_term" : 1,
"_routing" : "blog2",
"found" : true,
"_source" : {
"comment" : "Hello Hadoop",
"username" : "Bob",
"blog_comments_relation" : {
"name" : "comment",
"parent" : "blog2"
}
}
}
更新??檔
- 更新??檔不會(huì)影響到??檔
#更新子文檔
PUT my_blogs/_doc/comment3?routing=blog2
{
"comment": "Hello Hadoop???",
"blog_comments_relation": {
"name": "comment",
"parent": "blog2"
}
}
嵌套對(duì)象 v.s ???檔
Nested Object | Parent / Child | |
---|---|---|
優(yōu)點(diǎn) | ?檔存儲(chǔ)在?起互纯,讀取性能? | ???檔可以獨(dú)?更新 |
缺點(diǎn) | 更新嵌套的??檔時(shí)瑟幕,需要更新整個(gè)?檔 | 需要額外的內(nèi)存維護(hù)關(guān)系。讀取 性能相對(duì)差 |
適?場(chǎng)景 | ??檔偶爾更新,以查詢?yōu)橹?/td> | ??檔更新頻繁 |
課程demo
DELETE my_blogs
# 設(shè)定 Parent/Child Mapping
PUT my_blogs
{
"settings": {
"number_of_shards": 2
},
"mappings": {
"properties": {
"blog_comments_relation": {
"type": "join",
"relations": {
"blog": "comment"
}
},
"content": {
"type": "text"
},
"title": {
"type": "keyword"
}
}
}
}
#索引父文檔
PUT my_blogs/_doc/blog1
{
"title":"Learning Elasticsearch",
"content":"learning ELK @ geektime",
"blog_comments_relation":{
"name":"blog"
}
}
#索引父文檔
PUT my_blogs/_doc/blog2
{
"title":"Learning Hadoop",
"content":"learning Hadoop",
"blog_comments_relation":{
"name":"blog"
}
}
#索引子文檔
PUT my_blogs/_doc/comment1?routing=blog1
{
"comment":"I am learning ELK",
"username":"Jack",
"blog_comments_relation":{
"name":"comment",
"parent":"blog1"
}
}
#索引子文檔
PUT my_blogs/_doc/comment2?routing=blog2
{
"comment":"I like Hadoop!!!!!",
"username":"Jack",
"blog_comments_relation":{
"name":"comment",
"parent":"blog2"
}
}
#索引子文檔
PUT my_blogs/_doc/comment3?routing=blog2
{
"comment":"Hello Hadoop",
"username":"Bob",
"blog_comments_relation":{
"name":"comment",
"parent":"blog2"
}
}
# 查詢所有文檔
POST my_blogs/_search
{
}
#根據(jù)父文檔ID查看
GET my_blogs/_doc/blog2
# Parent Id 查詢
POST my_blogs/_search
{
"query": {
"parent_id": {
"type": "comment",
"id": "blog2"
}
}
}
# Has Child 查詢,返回父文檔
POST my_blogs/_search
{
"query": {
"has_child": {
"type": "comment",
"query" : {
"match": {
"username" : "Jack"
}
}
}
}
}
# Has Parent 查詢只盹,返回相關(guān)的子文檔
POST my_blogs/_search
{
"query": {
"has_parent": {
"parent_type": "blog",
"query" : {
"match": {
"title" : "Learning Hadoop"
}
}
}
}
}
#通過(guò)ID 辣往,訪問(wèn)子文檔
GET my_blogs/_doc/comment3
#通過(guò)ID和routing ,訪問(wèn)子文檔
GET my_blogs/_doc/comment3?routing=blog2
#更新子文檔
PUT my_blogs/_doc/comment3?routing=blog2
{
"comment": "Hello Hadoop??",
"blog_comments_relation": {
"name": "comment",
"parent": "blog2"
}
}
相關(guān)閱讀
- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-has-child-query.html
- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-has-parent-query.html
- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-parent-id-query.html
- https://www.elastic.co/guide/en/elasticsearch/reference/7.1/query-dsl-parent-id-query.html