h2.post_title { background-color: rgba(43, 102, 149, 1); color: rgba(255, 255, 255, 1); font-size: 18px !important; font-weight: bold !important; line-height: 38px !important; padding-left: 10px; border-radius: 4px }

在我的上一篇 《Elasticsearch 第七篇:父子结构mapping设计以及相关查询》中,通过建立电影索引库,将电影 film 与演员 actor 做了父子关系的联结,并做了相关查询,

但是实际上,父子关联查询并不是最推荐的设计方式。在实际应用中,通常要设计比较复杂的数据结构,才能满足业务需求的需要。

例如:一部电影通常会有多个标签tag,经常需要通过对 tag 进行过滤和查询;一部电影有多个演员,每个演员又包含姓名、性别等信息,怎样设计数据结构会比较合理呢?

这一篇,就针对电影库来简单说明。

注意,这里讨论的,都是 Elasticsearch 7.8 版本的,不同版本会有差异,请自行阅读相关资料。

一、Elasticsearch 数据类型

       基本数据类型:string(elasticsearch 7.x 版本之后分为 keyword 和 text ,区别是 keyword 支持排序、聚合,不支持分词;text 支持分词,不支持排序、聚合)、integer (整数类型)、boolean(布尔类型)、date(时间类型)等。

       特殊数据类型:geo_point(地理坐标类型)、ip(IP类型)等。

       复合类型:object(对象类型)、array(数组类型)、nested(嵌套类型)。

1、Object

个人认为 object 类型实际上并没有什么用途,完全可以把二级字段转化为一级字段,不需要特别地去做区分,所以不予讨论,可以见第七篇的父子结构设计。

2、Array

array 类型其实也是比较简单,例如现在有一部电影《画皮》,数据结构如下:

{
"id":"000-111-222",
"name":"画皮",
"desc":"该电影由聊斋改编,讲述的是...",
"tag":["古装","魔幻","爱情"]
}

现在希望Elasticsearch 也为这三个标签建立索引,在这样的应用场景下,就可以用 array 类型来保存电影的3个标签——古装、魔幻、爱情。

Elasticsearch 的数据映射可以这样定义:

{
"mappings": {
"properties": {
"tag": {
"type": "keyword"
},
...
}
}
}

这样,就可以提交数据,也可以通过 tag 标签来查询想要的电影,下文将会详细说明。

3、Nested

nested 类型,指的是嵌套类型,也是本节需要重点讲解的类型。什么时候用到嵌套类型呢?

还是以电影库作为例子,每一部电影都会有一个演员列表,每个演员有包含姓名、性别、年龄等等信息,如果我们不仅要搜索电影的基本信息,也希望能搜索演员的相关信息,那么,再这样的场景下,就可以用 nested 这样的数据类型,下文将会详细说明。

二、建立测试索引库

现在,建立电影索引库,涉及到三个主体:

1、电影  film  ,包括 id(编号)、name(电影名称)、desc (电影介绍)

2、电影标签 tag ,例如:爱情、战争、魔幻、古装

3、演员 actors , 包括 id(编号)、name(演员姓名)、sex (演员性别)

关联关系是:一部电影对应多个演员、一部电影对应多个标签

根据以上的分析,建立电影索引库 myfilm ,如下:

put http://localhost:9200/myfilm
{
"mappings": {
"properties": {
"id":{
"type": "keyword",
"store":true
},
"name":{
"type": "keyword",
"store":true
},
"desc":{
"type":"text",
"store":true,
"analyzer": "ik_max_word"
},
"tag":{
"type": "keyword",
"store":true
},
"actors":{
"type": "nested",
"properties":{
"id":{
"type": "keyword",
"store":true
},
"name":{
"type": "keyword",
"store":true
},
"sex":{
"type": "integer",
"store":true
}
}
}
}
}
}

现在可以往库插入数据《甄嬛传》,代码如下:

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

再加入测试数据《画皮》:

put  http://localhost:9200/myfilm/_doc/film_002

{
"id":"film_002",
"name":"画皮",
"desc":"秦汉年间,都尉王生率王家军在西域与沙匪激战中救回一绝色女子,并带回江都王府。对方为九霄美狐小唯披人皮所变。其皮必须用人心养护,故小唯的隐形助手小易,一只沙漠蜥蜴修成的妖,每隔几天便杀人取心供奉小唯,以表对小唯的爱意,江都城因此陷入一片恐怖中。小唯因王家军首领王生勇猛英俊对其萌生爱意,并不停用妖术诱惑王生,想取代王生妻子佩蓉的地位。王家军前统领庞勇武功高强,与王生、佩蓉情同手足,并暗恋佩蓉。后佩蓉嫁给王生,庞勇辞官出走成为流浪侠士。佩蓉发现小唯爱恋自己的丈夫,并觉察到她不是常人,暗中求助庞勇求他救助王生",
"tag":["神话","古装","爱情","恐怖","鬼神","聊斋"],
"actors":[
{
"id":"actor_101",
"name":"赵薇",
"sex":0
},
{
"id":"actor_102",
"name":"陈坤",
"sex":1
},
{
"id":"actor_103",
"name":"周迅",
"sex":0
},
{
"id":"actor_104",
"name":"孙俪",
"sex":0
},
{
"id":"actor_105",
"name":"甄子丹",
"sex":1
}
]
}

再加入数据《红高粱》:

http://localhost:9200/myfilm/_doc/film_003

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

三、Array 数据类型查询

上面已经建立了测试库 myfilm ,现在可以通过对标签 tag 进行过滤,来查询我们想要的电影。

场景:查询包含标签 “鬼神” 的影视作品,代码如下:

get  http://localhost:9200/myfilm/_search
{
"query": {
"bool":{
"must":[
{"match":{"tag":"鬼神"}}
]
}
}
}

这时,电影《画皮》被搜索出来,与上面测试数据对比,是预期的效果。

考虑到标签大部分时候是一个词,不需要分词,所以上面 tag 数据类型设置为 keyword ,如果标签是一段文本,也可以将 tag 类型设置为 text ,并进行分词,但在这个应用场景中,用 keyword 即可。

四、Nested 数据类型查询

现在,可以对子级列表,也就是通过对演员 actors 的筛选,来搜索电影。

1、场景:搜索周迅演过的作品

这时候通过简单地文字对比即可,但是查询语句会有 “nested” 标记,嵌套比较多,如下

get  http://localhost:9200/myfilm/_search
{
"query": {
"bool":{
"must":[
{
"nested":{
"path":"actors",
"query":{
"bool":{
"must":[
{
"match":{"actors.name":"周迅"}
}
]
}
}
}
}
]
}
}
}

这时候《画皮》、《红高粱》都命中,与预期相吻合,如果只想查出一部,还可以加过滤条件,例如  actors.name=“周迅”  actors.id=actor_201 ,这时候是:

get  http://localhost:9200/myfilm/_search

{
"query": {
"bool":{
"must":[
{
"nested":{
"path":"actors",
"query":{
"bool":{
"must":[
{
"match":{"actors.name":"周迅"}
}
]
}
}
}
}
]
}
}
}

2、场景:查询周迅演过的、民国时期的作品

分析:这个场景中,涉及到父子条件的综合查询,子级需要筛选演员名字,父级需要查询标签包含 “民国” ,查询条件会比较复杂,但是思路还是很清晰的,如下

http://localhost:9200/myfilm/_search

{
"query": {
"bool":{
"must":[
{
"nested":{
"path":"actors",
"query":{
"bool":{
"must":[
{
"term":{"actors.name":"周迅"}
}
]
}
}
}
},
{
"term":{"tag":"民国"}
}
]
}
}
}

Nested 还可以增加、修改、删除,最简单粗暴的方法,就是直接覆盖某一部电影,当然还有更小范围的修改,有时间我再记录一下!

Elasticsearch 第八篇:数据类型 Array、Nested、Object 的设计与应用的更多相关文章

  1. ElasticSearch入门 第八篇:存储

    这是ElasticSearch 2.4 版本系列的第八篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  2. typeof操作符,返回数据类型Array.isArray()、Object.prototype.toString.call()

    源地址https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/typeof typeof操作符 // N ...

  3. 第八篇 SQL Server安全数据加密

    本篇文章是SQL Server安全系列的第八篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...

  4. 【译】第八篇 SQL Server安全数据加密

    本篇文章是SQL Server安全系列的第八篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...

  5. ElasticSearch入门 第二篇:集群配置

    这是ElasticSearch 2.4 版本系列的第二篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  6. ElasticSearch入门 第一篇:Windows下安装ElasticSearch

    这是ElasticSearch 2.4 版本系列的第一篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  7. ElasticSearch入门 第九篇:实现正则表达式查询的思路

    这是ElasticSearch 2.4 版本系列的第九篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  8. 解剖SQLSERVER 第三篇 数据类型的实现(译)

    解剖SQLSERVER 第三篇  数据类型的实现(译) http://improve.dk/implementing-data-types-in-orcamdf/ 实现对SQLSERVER数据类型的解 ...

  9. Python之路【第十八篇】:Web框架们

    Python之路[第十八篇]:Web框架们   Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Pytho ...

随机推荐

  1. linux(centos8):安装jmeter5.3

    一,jmeter的用途: Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试, 它最初被设计用于Web应用测试,但后来扩展到其他测试领域.  Apach ...

  2. centos8平台用ffprobe获取视频文件信息(ffmpeg4.2.2)

    一,ffprobe的作用 ffprobe是强大的视频分析工具, 用于从多媒体流中获取相关信息或查看文件格式信息, 并以可读的方式打印 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https:// ...

  3. 忘记MySQL密码怎么办?一招教你搞定!

    在安装完 MySQL 或者是在使用 MySQL 时,最尴尬的就是忘记密码了,墨菲定律也告诉我们,如果一件事有可能出错,那么它一定会出错.那如果我们不小心忘记了 MySQL 的密码,该如何处理呢?别着急 ...

  4. springboot添加拦截器

    一,编写拦截器 public class TokenInterceptor implements HandlerInterceptor { @Override public boolean preHa ...

  5. Java进阶面试

    消息中间件: 1.你们公司生产环境用的是什么消息中间件? https://mp.weixin.qq.com/s?__biz=MzU0OTk3ODQ3Ng==&mid=2247484149&am ...

  6. IDEA配置类和方法注释模板

    1定义java文件头部的注释 2给java类中的方法添加上注释 2.1第一步勾选Enable Live  Templates 2.2第二步新建一个Group 2.3第三步新建一个Template 2. ...

  7. Spring Boot学习笔记(二)——HelloWorld实现

    提示:要在Eclipse里使用Spring Boot,首先要安装STS插件,前面我们已经安装了STS插件了,可以创建Spring Boot项目了. 1.创建项目: 新建项目,选择Spring Boot ...

  8. D. Rescue Nibel! 解析(思維、組合、離散化、差分)

    Codeforce 1420 D. Rescue Nibel! 解析(思維.組合.離散化.差分) 今天我們來看看CF1420D 題目連結 題目 給你\(n\)個區間,求有幾種方法使得\(k\)個區間的 ...

  9. ABP 数据访问 - IRepository 仓储

    ABP系列,这个系列来的比较晚,很多大佬其实已经分析过,为什么现在我又来一轮呢? 1.想自己来完整的学习一轮ABP 2.公司目前正在使用ABP,准备迁移Core 基于以上的目的,开始这个系列 ABP ...

  10. 【转】Liunx常用命令详解

    Liuux命令查询入口 Linux命令 - 系统信息 命令代码 注释说明 arch 显示机器的处理器架构(1) uname -m 显示机器的处理器架构(2) uname -r 显示正在使用的内核版本 ...