Elasticsearch 第七篇:父子结构mapping设计以及相关查询

      首先在 Elasticsearch 较高版本中,是抛弃掉 type 这一概念的,我们做搜索时,时常需要涉及到父子数据结构,以下通过建立电影索引库,来示范一下。

      一部电影有多个演员,父级为电影 film ,子级为演员 actor 。

第一步 mapping设计

      在以下代码中,注意一对多是如何通过 relation 属性来连接的,直接看代码:

put  http://localhost:9200/filmdb
{ 
    "mappings": { 
            "properties": { 
                "film":{
                    "properties":{
                        "id":{
                            "type": "keyword",
                            "store":true
                        },
                        "name":{
                            "type": "keyword",
                            "store":true
                        },
                        "desc":{
                            "type":"text",
                            "store":true,
                            "analyzer": "ik_max_word"
                        }
                    }
                },
                "actor":{
                    "properties":{
                        "id":{
                            "type": "keyword",
                            "store":true
                        },
                        "name":{
                            "type": "keyword",
                            "store":true
                        },
                        "sex":{
                            "type": "integer",
                            "store":true
                        }
                    }
                },
                "relation": {
                      "type": "join",
                      "relations": {
                          "film": ["actor"]
                      }
               }
        } 
    } 
}

 以上映射中,film(包含编号Id、名称name、介绍desc) 与 actor(编号id、名称name、性别sex,其中sex=1表示男演员,sex=0表示女演员) 是并列的,通过 relation 属性,将父级 film 与 子级 actor 连接起来(join),而且是一对多的关系,见

以上relation中,film 对应数组的 actor 。

第二步 添加测试数据

1、添加作品《甄嬛传》

作品《甄嬛传》的 id 等于 “zhenhuan” 当然,也可以是数字1,而且要表明是父级 relation=film

put  http://localhost:9200/filmdb/_doc/zhenhuan
{
    "film.id":"zhenhuan",
    "film.name":"甄嬛传",
    "film.desc":"雍正元年,结束了血腥的夺位之争,新的君主(陈建斌 饰)继位,国泰民安,政治清明,但在一片祥和的表象之下,一股暗流蠢蠢欲动,尤其后宫,华妃(蒋欣 饰)与皇后(蔡少芬 饰)分庭抗礼,各方势力裹挟其中,凶险异常。十七岁的甄嬛(孙俪饰)与好姐妹眉庄(斓曦饰)、陵容(陶昕然饰)参加选秀,她本抱着来充个数的念头,可皇帝(陈建斌饰)偏相中了她的智慧、气节与端庄,最后三人一同入选。但因华妃(蒋欣饰)嚣张,步步紧逼,眉庄被冤,陵容变心,天真的甄嬛慢慢变成了后宫精明的女子。皇帝发现年羹尧(孙宁饰)的野心,令甄父剪除年氏一族,甄嬛终于斗倒了华妃。但由于甄嬛与先故纯元皇后的神似,皇后设计以纯元皇后的礼服陷害甄嬛,父亲(沈保平饰)也被文字狱牵连和奸人陷害而遭牢狱之灾,生下女儿后,心灰意冷的甄嬛选择出宫修行。在宫外幸得十七爷允礼(李东学饰)悉心照顾,二人相亲相爱,只等有机会远走高飞。后因误传十七爷死讯,甄嬛为保全腹中骨肉,设计与皇帝相遇,狠心断绝对十七爷的爱恋,重回宫中,再度与皇后相斗。后因生下双生子,同时甄父的冤案得以平反,重新被皇帝重用,甄氏一族再度崛起。甄嬛多次躲过皇后的陷害,最终扳倒皇后。可造化弄人,由于皇帝的疑心,最终却只能看着心上人允礼死在自己怀中,而与叶澜依(热依扎饰)合谋弑君。皇帝驾崩后,甄嬛养子弘历登基,甄嬛被尊为圣母皇太后,即便享尽荣华,但眼见一生姐妹沈眉庄血崩而亡,一生爱人允礼为保其周全而无憾自尽,不过是一代封建王朝的悲情故梦罢了。",
    "relation":"film"
}

添加演员孙俪,注意:演员的 id=101 ,这里需要注意 routing 指向父级id,即是 “zhenhuan”,同样,relation 中也是指定父级编号是“zhenhuan”,relation 中 name=actor 表明是子级关系。

post  http://localhost:9200/filmdb/_doc/101?routing=zhenhuan
{ 
  "actor.id":"101",
  "actor.name":"孙俪",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"zhenhuan"
  }
}

添加演员陈建斌

post  http://localhost:9200/filmdb/_doc/102?routing=zhenhuan
{ 
  "actor.id":"102",
  "actor.name":"陈建斌",
  "actor.sex":1,
  "relation":
  {
    "name":"actor",
    "parent":"zhenhuan"
  }
}

添加演员蔡少芬

post  http://localhost:9200/filmdb/_doc/103?routing=zhenhuan
{ 
  "actor.id":"103",
  "actor.name":"蔡少芬",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"zhenhuan"
  }
}

添加演员蓝盈盈

post  http://localhost:9200/filmdb/_doc/104?routing=zhenhuan
{ 
  "actor.id":"104",
  "actor.name":"蓝盈盈",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"zhenhuan"
  }
}

添加演员蒋欣

post  http://localhost:9200/filmdb/_doc/105?routing=zhenhuan
{ 
  "actor.id":"105",
  "actor.name":"蒋欣",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"zhenhuan"
  }
}

2、添加电影《画皮》

put  http://localhost:9200/filmdb/_doc/huapi
{
    "film.id":"huapi",
    "film.name":"画皮",
    "film.desc":"秦汉年间,都尉王生率王家军在西域与沙匪激战中救回一绝色女子,并带回江都王府。对方为九霄美狐小唯披人皮所变。其皮必须用人心养护,故小唯的隐形助手小易,一只沙漠蜥蜴修成的妖,每隔几天便杀人取心供奉小唯,以表对小唯的爱意,江都城因此陷入一片恐怖中。小唯因王家军首领王生勇猛英俊对其萌生爱意,并不停用妖术诱惑王生,想取代王生妻子佩蓉的地位。王家军前统领庞勇武功高强,与王生、佩蓉情同手足,并暗恋佩蓉。后佩蓉嫁给王生,庞勇辞官出走成为流浪侠士。佩蓉发现小唯爱恋自己的丈夫,并觉察到她不是常人,暗中求助庞勇求他救助王生",
    "relation":"film"
}

添加演员赵薇

put  http://localhost:9200/filmdb/_doc/201?routing=huapi
{ 
  "actor.id":"201",
  "actor.name":"赵薇",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"huapi"
  }
}

添加演员周迅

put  http://localhost:9200/filmdb/_doc/202?routing=huapi
{ 
  "actor.id":"202",
  "actor.name":"周迅",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"huapi"
  }
}

添加演员孙俪

put  http://localhost:9200/filmdb/_doc/203?routing=huapi
{ 
  "actor.id":"203",
  "actor.name":"孙俪",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"huapi"
  }
}

添加演员甄子丹

put  http://localhost:9200/filmdb/_doc/204?routing=huapi
{ 
  "actor.id":"204",
  "actor.name":"甄子丹",
  "actor.sex":1,
  "relation":
  {
    "name":"actor",
    "parent":"huapi"
  }
}

添加演员陈坤

put  http://localhost:9200/filmdb/_doc/205?routing=huapi
{ 
  "actor.id":"205",
  "actor.name":"陈坤",
  "actor.sex":1,
  "relation":
  {
    "name":"actor",
    "parent":"huapi"
  }
}

 3、添加作品《红高粱》

put  http://localhost:9200/filmdb/_doc/honggaoliang
{
    "film.id":"honggaoliang",
    "film.name":"红高粱",
    "film.desc":"20世纪30年代初,山东高密地区土匪横行,民不聊生。东北乡破落地主家19岁的女儿九儿,被贪财的父亲许给了麻风病的酒坊主儿子单扁郎,孔武有力的杠子头余占鳌喜欢九儿,杀掉了单家父子,九儿和余占鳌开始了一段不被乡民认可的爱情,并有了两个孩子。在酿酒师傅罗汉等人的帮助下,九儿逐渐从一个单纯的少女成长为干练的高粱酒坊女掌柜, 振兴了单家酒坊。余占鳌则带领兄弟们组成自己的武装力量,周旋于当地政府,土匪花脖子以及铁板会等多股势力之间。七七事变爆发,日军进占山东,打破了高密县往日的繁荣,在民族大义面前,余占鳌和各方势力不计前嫌,停止争端,共同抗日。内忧外患之际,九儿带领队伍,将日本鬼子引到了高粱地,点燃红高粱,与敌人同归于尽,用自己的生命在这片充满生命力的山东高密大地上撰写了爱与征服,野心和意志的传奇故事。",
    "relation":"film"
}

添加演员周迅

put  http://localhost:9200/filmdb/_doc/301?routing=honggaoliang
{ 
  "actor.id":"301",
  "actor.name":"周迅",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"honggaoliang"
  }
}

添加演员朱亚文

put  http://localhost:9200/filmdb/_doc/302?routing=honggaoliang
{ 
  "actor.id":"302",
  "actor.name":"朱亚文",
  "actor.sex":1,
  "relation":
  {
    "name":"actor",
    "parent":"honggaoliang"
  }
}

添加演员于荣光

put  http://localhost:9200/filmdb/_doc/303?routing=honggaoliang
{ 
  "actor.id":"303",
  "actor.name":"于荣光",
  "actor.sex":1,
  "relation":
  {
    "name":"actor",
    "parent":"honggaoliang"
  }
}

添加演员秦海璐

put  http://localhost:9200/filmdb/_doc/304?routing=honggaoliang
{ 
  "actor.id":"304",
  "actor.name":"秦海璐",
  "actor.sex":0,
  "relation":
  {
    "name":"actor",
    "parent":"honggaoliang"
  }
}

 

第三步 基本查询

1、以子查父

例如:查询演员孙俪的所有的作品

这里直接通过 term 来查询,也就是姓名等于“孙俪”,“has_child” 表示通过对子级数据进行筛选,type表明子级的数据是actor。

get  http://localhost:9200/filmdb/_search
{
  "query": {
    "has_child": {
      "type": "actor",
      "query": {
        "term": {
          "actor.name": "孙俪"
        }
      }
    }
  }
}

查询结果是:

{
    "took": 5,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1,
        "hits": [
            {
                "_index": "filmdb",
                "_type": "_doc",
                "_id": "zhenhuan",
                "_score": 1,
                "_source": {
                    "film.id": "zhenhuan",
                    "film.name": "甄嬛传",
                    "film.desc": "雍正元年,结束了血腥的夺位之争,新的君主(陈建斌 饰)继位,国泰民安,政治清明,但在一片祥和的表象之下,一股暗流蠢蠢欲动,尤其后宫,华妃(蒋欣 饰)与皇后(蔡少芬 饰)分庭抗礼,各方势力裹挟其中,凶险异常。十七岁的甄嬛(孙俪饰)与好姐妹眉庄(斓曦饰)、陵容(陶昕然饰)参加选秀,她本抱着来充个数的念头,可皇帝(陈建斌饰)偏相中了她的智慧、气节与端庄,最后三人一同入选。但因华妃(蒋欣饰)嚣张,步步紧逼,眉庄被冤,陵容变心,天真的甄嬛慢慢变成了后宫精明的女子。皇帝发现年羹尧(孙宁饰)的野心,令甄父剪除年氏一族,甄嬛终于斗倒了华妃。但由于甄嬛与先故纯元皇后的神似,皇后设计以纯元皇后的礼服陷害甄嬛,父亲(沈保平饰)也被文字狱牵连和奸人陷害而遭牢狱之灾,生下女儿后,心灰意冷的甄嬛选择出宫修行。在宫外幸得十七爷允礼(李东学饰)悉心照顾,二人相亲相爱,只等有机会远走高飞。后因误传十七爷死讯,甄嬛为保全腹中骨肉,设计与皇帝相遇,狠心断绝对十七爷的爱恋,重回宫中,再度与皇后相斗。后因生下双生子,同时甄父的冤案得以平反,重新被皇帝重用,甄氏一族再度崛起。甄嬛多次躲过皇后的陷害,最终扳倒皇后。可造化弄人,由于皇帝的疑心,最终却只能看着心上人允礼死在自己怀中,而与叶澜依(热依扎饰)合谋弑君。皇帝驾崩后,甄嬛养子弘历登基,甄嬛被尊为圣母皇太后,即便享尽荣华,但眼见一生姐妹沈眉庄血崩而亡,一生爱人允礼为保其周全而无憾自尽,不过是一代封建王朝的悲情故梦罢了。",
                    "relation": "film"
                }
            },
            {
                "_index": "filmdb",
                "_type": "_doc",
                "_id": "huapi",
                "_score": 1,
                "_source": {
                    "film.id": "huapi",
                    "film.name": "画皮",
                    "film.desc": "秦汉年间,都尉王生率王家军在西域与沙匪激战中救回一绝色女子,并带回江都王府。对方为九霄美狐小唯披人皮所变。其皮必须用人心养护,故小唯的隐形助手小易,一只沙漠蜥蜴修成的妖,每隔几天便杀人取心供奉小唯,以表对小唯的爱意,江都城因此陷入一片恐怖中。小唯因王家军首领王生勇猛英俊对其萌生爱意,并不停用妖术诱惑王生,想取代王生妻子佩蓉的地位。王家军前统领庞勇武功高强,与王生、佩蓉情同手足,并暗恋佩蓉。后佩蓉嫁给王生,庞勇辞官出走成为流浪侠士。佩蓉发现小唯爱恋自己的丈夫,并觉察到她不是常人,暗中求助庞勇求他救助王生",
                    "relation": "film"
                }
            }
        ]
    }
}

可见《甄嬛传》、《画皮》都被查了出来。

2、以父查子

例如:查询演过后宫题材的演员

这里通过match关键字来进行匹配,“has_parent” 表明是通过对父级数据进行筛选,从而达到查询子结构的目的。

get  http://localhost:9200/filmdb/_search
{
  "query": {
    "has_parent": {
      "parent_type": "film",
      "query": {
        "match": {
          "film.desc": "后宫"
          }
        }
      }
    }  
}

查询结果是:

{
    "took": 4,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 5,
            "relation": "eq"
        },
        "max_score": 1,
        "hits": [
            {
                "_index": "filmdb",
                "_type": "_doc",
                "_id": "101",
                "_score": 1,
                "_routing": "zhenhuan",
                "_source": {
                    "actor.id": "101",
                    "actor.name": "孙俪",
                    "actor.sex": 0,
                    "relation": {
                        "name": "actor",
                        "parent": "zhenhuan"
                    }
                }
            },
            {
                "_index": "filmdb",
                "_type": "_doc",
                "_id": "102",
                "_score": 1,
                "_routing": "zhenhuan",
                "_source": {
                    "actor.id": "102",
                    "actor.name": "陈建斌",
                    "actor.sex": 1,
                    "relation": {
                        "name": "actor",
                        "parent": "zhenhuan"
                    }
                }
            },
            {
                "_index": "filmdb",
                "_type": "_doc",
                "_id": "103",
                "_score": 1,
                "_routing": "zhenhuan",
                "_source": {
                    "actor.id": "103",
                    "actor.name": "蔡少芬",
                    "actor.sex": 0,
                    "relation": {
                        "name": "actor",
                        "parent": "zhenhuan"
                    }
                }
            },
            {
                "_index": "filmdb",
                "_type": "_doc",
                "_id": "104",
                "_score": 1,
                "_routing": "zhenhuan",
                "_source": {
                    "actor.id": "104",
                    "actor.name": "蓝盈盈",
                    "actor.sex": 0,
                    "relation": {
                        "name": "actor",
                        "parent": "zhenhuan"
                    }
                }
            },
            {
                "_index": "filmdb",
                "_type": "_doc",
                "_id": "105",
                "_score": 1,
                "_routing": "zhenhuan",
                "_source": {
                    "actor.id": "105",
                    "actor.name": "蒋欣",
                    "actor.sex": 0,
                    "relation": {
                        "name": "actor",
                        "parent": "zhenhuan"
                    }
                }
            }
        ]
    }
}

可见,《甄嬛传》的所有的演员都命中查询条件,

其它复杂的查询,以后想到再更新博文。

 

posted @ 2020-11-17 09:43  vincentfhr方海荣  阅读(645)  评论(0编辑  收藏  举报