Elasticsearch 第八篇:数据类型 Array、Nested、Object 的设计与应用
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 的设计与应用的更多相关文章
- ElasticSearch入门 第八篇:存储
这是ElasticSearch 2.4 版本系列的第八篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...
- typeof操作符,返回数据类型Array.isArray()、Object.prototype.toString.call()
源地址https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/typeof typeof操作符 // N ...
- 第八篇 SQL Server安全数据加密
本篇文章是SQL Server安全系列的第八篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...
- 【译】第八篇 SQL Server安全数据加密
本篇文章是SQL Server安全系列的第八篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...
- ElasticSearch入门 第二篇:集群配置
这是ElasticSearch 2.4 版本系列的第二篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...
- ElasticSearch入门 第一篇:Windows下安装ElasticSearch
这是ElasticSearch 2.4 版本系列的第一篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...
- ElasticSearch入门 第九篇:实现正则表达式查询的思路
这是ElasticSearch 2.4 版本系列的第九篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...
- 解剖SQLSERVER 第三篇 数据类型的实现(译)
解剖SQLSERVER 第三篇 数据类型的实现(译) http://improve.dk/implementing-data-types-in-orcamdf/ 实现对SQLSERVER数据类型的解 ...
- Python之路【第十八篇】:Web框架们
Python之路[第十八篇]:Web框架们 Python的WEB框架 Bottle Bottle是一个快速.简洁.轻量级的基于WSIG的微型Web框架,此框架只由一个 .py 文件,除了Pytho ...
随机推荐
- docker 启动redis/nginx
1.docker 启动redis # redis docker run -itd --name redis-test -p 16379:6379 redis 2.docker 启动nginx ...
- selenium分布式启动(deepin)
1.deepin安装jdk: 下载地址:链接:https://pan.baidu.com/s/19-pU8G6RzMW92uBCxBH7sA 密码:1c7n 解压:tar -zxvf jdk-8u20 ...
- 用 Span 对 C# 进程中三大内存区域进行统一访问 ,太厉害了!
一:背景 1. 讲故事 前段时间写了几篇 C# 漫文,评论留言中有很多朋友多次提到 Span,周末抽空看了下,确实是一个非常
- PPT神器
今天要给大家推荐一款开挂一般的 PPT 插件:iSlide 强烈推荐大家下载使用哈,绝对分分钟让你做出美观大气的 PPT! 不管是老师.学生还是公司人员,PPT 都是必须要掌握的技能,然而要 ...
- Java面试题集(一)答案汇总(1-22)
java基础篇: 1.1.Java基础 (1)面向对象的特性:继承.封装和多态 以下都是查阅大神的博客后,摘录的内容:来源http://www.cnblogs.com/chenssy 1.继承 继承是 ...
- Java学习的第四十四天
1.例5.4将二维数组的行列互换 public class cjava { public static void main(String []args) { int [][]a=new int [][ ...
- Learn day10 锁
1.锁 # ### 锁 from multiprocessing import Lock,Process import json,time """ # 创建一把锁 loc ...
- python数据类型之String(字符串)
String(字符串) 1.概述 字符串是以单引号或双引号括起来的任意文本,比如"abc",'xy'等等,请注意''或者""本身只是一种表示方式,并不是字符 ...
- [Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3119 Solution 这题显然要先把缩点做了. 然后我们就可以考虑如何处理走反向边的问题. 像我这样的 ...
- [Luogu P4147] 玉蟾宫 (网格DP)
题面 传送门:https://www.luogu.org/problemnew/show/P4147 Solution 裸的求极大子矩阵 感谢wzj dalao的教学 首先,有一个很显然但很重要的结论 ...