数组如何在ElasticSearch中索引
一、简介
在ElasticSearch里没有专门的数组类型,任何一个字段都可以有零个和多个值。当字段值的个数大于1时,字段类型就变成了数组。
下面以视频数据为例,介绍ElasticSearch如何索引数组数据,以及如何检索数组中的字段值。
测试视频数据格式如下:
{
"media_id": 88992211,
"tags": ["电影","科技","恐怖","电竞"]
}
media_id代表视频id,tags是视频的标签,有多个值。业务上需要按视频标签检索标签下所有的视频。同一个视频有多个标签。
演示使用的ElasticSearch集群的版本是7.6.2。
二、测试演示
2.1 创建索引
PUT test_arrays
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"properties": {
"media_id": {
"type": "long"
},
"tags": {
"type": "text"
}
}
}
}
2.2 向test_arrays索引里写入测试数据
POST test_arrays/_doc
{
"media_id": 887722,
"tags": [
"电影",
"科技",
"恐怖",
"电竞"
]
}
2.3 查看test_arrays内部如何索引tags字段
{
"tokens" : [
{
"token" : "电",
"start_offset" : 0,
"end_offset" : 1,
"type" : "<IDEOGRAPHIC>",
"position" : 0
},
{
"token" : "影",
"start_offset" : 1,
"end_offset" : 2,
"type" : "<IDEOGRAPHIC>",
"position" : 1
},
{
"token" : "科",
"start_offset" : 3,
"end_offset" : 4,
"type" : "<IDEOGRAPHIC>",
"position" : 102
},
{
"token" : "技",
"start_offset" : 4,
"end_offset" : 5,
"type" : "<IDEOGRAPHIC>",
"position" : 103
},
{
"token" : "恐",
"start_offset" : 6,
"end_offset" : 7,
"type" : "<IDEOGRAPHIC>",
"position" : 204
},
{
"token" : "怖",
"start_offset" : 7,
"end_offset" : 8,
"type" : "<IDEOGRAPHIC>",
"position" : 205
},
{
"token" : "电",
"start_offset" : 9,
"end_offset" : 10,
"type" : "<IDEOGRAPHIC>",
"position" : 306
},
{
"token" : "竞",
"start_offset" : 10,
"end_offset" : 11,
"type" : "<IDEOGRAPHIC>",
"position" : 307
}
]
}
从响应结果可以看到,tags数组中的每个值被分词成多个token。
2.4 检索tags数组中的值
POST test_arrays/_search
{
"query": {
"match": {
"tags": "电影"
}
}
}
响应结果:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.68324494,
"hits" : [
{
"_index" : "test_arrays",
"_type" : "_doc",
"_id" : "MyhnpXQBGXOapfjvSpOW",
"_score" : 0.68324494,
"_source" : {
"media_id" : 887722,
"tags" : [
"电影",
"科技",
"恐怖",
"电竞"
]
}
}
]
}
}
模糊检索:
POST test_arrays/_search
{
"query": {
"match": {
"tags": "影"
}
}
}
响应结果
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "test_arrays",
"_type" : "_doc",
"_id" : "MyhnpXQBGXOapfjvSpOW",
"_score" : 0.2876821,
"_source" : {
"media_id" : 887722,
"tags" : [
"电影",
"科技",
"恐怖",
"电竞"
]
}
}
]
}
}
视频数据业务上需要通过标签精确匹配,查询标签下的所有视频。实现这种效果,需要把tags字段类型修改为keyword。test_arrays索引的mappings设置如下:
PUT test_arrays
{
"settings": {
"number_of_shards": 1
},
"mappings": {
"properties": {
"media_id": {
"type": "long"
},
"tags": {
"type": "keyword"
}
}
}
}
此时tags字段数组中每一个值对应一个token,可以实现按标签精准查询标签下视频的效果。
{
"tokens" : [
{
"token" : "电影",
"start_offset" : 0,
"end_offset" : 2,
"type" : "word",
"position" : 0
},
{
"token" : "科技",
"start_offset" : 3,
"end_offset" : 5,
"type" : "word",
"position" : 1
},
{
"token" : "恐怖",
"start_offset" : 6,
"end_offset" : 8,
"type" : "word",
"position" : 2
},
{
"token" : "电竞",
"start_offset" : 9,
"end_offset" : 11,
"type" : "word",
"position" : 3
}
]
}
实际业务场景中,视频标签的数据可能不是按数组存储的,全部标签存储在一个字符串中,标签之间用逗号分隔。
{
"media_id": 88992211,
"tags": "电影,科技,恐怖,电竞"
}
上面的标签存储格式,通过调整索引字段的类型,同样可以实现精准检索单个标签下视频的效果。test_arrays索引的配置如下:
PUT test_arrays
{
"settings": {
"number_of_shards": 1,
"analysis" : {
"analyzer" : {
"comma_analyzer": {
"tokenizer": "comma_tokenizer"
}
},
"tokenizer" : {
"comma_tokenizer": {
"type": "simple_pattern_split",
"pattern": ","
}
}
}
},
"mappings": {
"properties": {
"media_id": {
"type": "long"
},
"tags": {
"search_analyzer" : "simple",
"analyzer" : "comma_analyzer",
"type" : "text"
}
}
}
}
写入一条测试数据到test_arrays索引
POST test_arrays/_doc
{
"media_id": 887722,
"tags": "电影,科技,恐怖,电竞"
}
tags字段的索引结构如下,同样实现了一个标签对应一个token。
{
"tokens" : [
{
"token" : "电影",
"start_offset" : 0,
"end_offset" : 2,
"type" : "word",
"position" : 0
},
{
"token" : "科技",
"start_offset" : 3,
"end_offset" : 5,
"type" : "word",
"position" : 1
},
{
"token" : "恐怖",
"start_offset" : 6,
"end_offset" : 8,
"type" : "word",
"position" : 2
},
{
"token" : "电竞",
"start_offset" : 9,
"end_offset" : 11,
"type" : "word",
"position" : 3
}
]
}
通过标签精准匹配查询。
请求参数
POST test_arrays/_search
{
"query": {
"match": {
"tags": "电影"
}
}
}
响应结果
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "test_arrays",
"_type" : "_doc",
"_id" : "3i2ipXQBGXOapfjv3THH",
"_score" : 0.2876821,
"_source" : {
"media_id" : 887722,
"tags" : "电影,科技,恐怖,电竞"
}
}
]
}
}
三、总结
ElasticSearch采用的一种数据类型同时支持单值和多值的设计理念,即简化了数据类型的总量,同时也降低索引配置的复杂度,是一种非常优秀的设计。
同时标签数据的组织方式支持数组和分隔符分隔两种形式,体现了ElasticSearch功能的灵活性。
数组如何在ElasticSearch中索引的更多相关文章
- 为何在查询中索引未被使用 (Doc ID 1549181.1)
To Bottom * 为何在查询中索引未被使用 (Doc ID 1549181.1) To Bottom 文档内容 用途 排错步骤 高速检查 表上是否存在索引? 索引是否应该 ...
- 如何在Elasticsearch中安装中文分词器(IK+pinyin)
如果直接使用Elasticsearch的朋友在处理中文内容的搜索时,肯定会遇到很尴尬的问题--中文词语被分成了一个一个的汉字,当用Kibana作图的时候,按照term来分组,结果一个汉字被分成了一组. ...
- 如何在Elasticsearch中解析未分配的分片(unassigned shards)
一.精确定位到有问题的shards 1.查看哪些分片未被分配 curl -XGET localhost:9200/_cat/shards?h=index,shard,prirep,state,unas ...
- 更改elasticsearch中索引的mapping
文章转载自:https://www.cnblogs.com/uglyliu/p/12331964.html 昨天研发说在kibana中统计userid字段不出图,后来查到该字段显示冲突了,然后再查看了 ...
- 如何在elasticsearch中查看Logstash打到elasticsearch的数据
# cat syslog02.conf #filename:syslog02.conf #注意这个是要用#号注释掉 input{ file{ path => ["/var/log/*. ...
- 如何在Elasticsearch中安装中文分词器(IK)和拼音分词器?
声明:我使用的Elasticsearch的版本是5.4.0,安装分词器前请先安装maven 一:安装maven https://github.com/apache/maven 说明: 安装maven需 ...
- 如何在Elasticsearch中使用pipeline API来对事件进行处理
一个processor就像是Logstash里的一个filter pipeline是一组processor
- 如何在python中使用Elasticsearch
什么是 Elasticsearch 想查数据就免不了搜索,搜索就离不开搜索引擎,百度.谷歌都是一个非常庞大复杂的搜索引擎,他们几乎索引了互联网上开放的所有网页和数据.然而对于我们自己的业务数据来说 ...
- Elasticsearch 中为什么选择倒排索引而不选择 B 树索引
目录 前言 为什么全文索引不使用 B+ 树进行存储 全文检索 正排索引 倒排索引 倒排索引如何存储数据 FOR 压缩 RBM 压缩 倒排索引如何存储 字典树(Tria Tree) FST FSM 构建 ...
随机推荐
- 使用正则表达式限制<kbd>QLineEdit</kbd>不能输入大于某个整数
使用正则表达式限制QLineEdit不能输入大于某个整数,即:使用正则表达式,匹配不大于某个整数 举例:匹配不大于4567 * 原理分析: 匹配不大于4567这个数,所以第一个想到的是只要小于4567 ...
- Reinforcement Learning Using a Continuous Time Actor-Critic Framework with Spiking Neurons
郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Abstract 动物会重复奖励的行为,但基于奖励的学习的生理基础仅得到了部分阐明.一方面,实验证据表明神经调节剂多巴胺携带有关奖励的信息 ...
- TCP/IP网络编程之socket交互流程
一.概要 本篇文章主要讲解基于.net中tcp/ip网络通信编程.在自我进步的过程中记录这些内容,方便自己记忆的同时也希望可以帮助到大家.技术的进步源自于分享和不断的自我突破. 技术交流QQ群:580 ...
- JVM 垃圾收集算法 标记-清楚、标记-复制、标记-整理
摘要 Java程序在运行过程中会产生大量的对象,但是内存大小是有限的,如果光用而不释放,那内存迟早被耗尽.如C.C++程序,需要程序员手动释放内存,Java则不需要,是由垃圾回收器去自动回收. 垃圾回 ...
- JAVA中 错误代码是 the public type must be defined in its own file 解决方法 android开发 java编程
一般是由于定义的JAVA类同文件名不一致: 解决方法: 1.把文件名修改同XYZ一样的名字: 2.把类名修改成同文件名:
- 腾讯大牛半年心血高级编程PDF,帮你轻松构建企业级Web应用
毫无疑问,Java 是这些年来最流行的编程语言之一.它无处不在一计算机. 手机.网站以及各种嵌入式设备中都存在着大量的Java 应用程序,而其中应用最为广泛的应该就是Java EE Web应用程序(以 ...
- Fitness - 05.23
倒计时222天 运动40分钟,共计8组,4.2公里.拉伸10分钟. 每组跑步3分钟(6.5KM/h),走路2分钟(5.5KM/h). 终于赶在姨妈前完成第3周的跑步训练了,可喜可贺~~ 下周预计要休息 ...
- Spine学习六 - 碰撞检测
相信在使用Spine做游戏的时候,肯定会遇到这样的需求: 一个人物有一把大刀,要使用这把大刀去砍怪,伤害检测以这把大刀砍刀怪物为准,那么要怎么在一个看上去就是一体的Spine Object上绑定一个碰 ...
- springboot @valid与@validated的参数校验使用总结
好久没在这平台写博客了,最近整理了这东西,先给出总结 // @Valid只能用在controller,@Validated可以用在其他被spring管理的类上 // @Valid可以加在成员变量上(本 ...
- 据说是最好的记忆工具——Anki
http://www.ankichina.net/ .u1s1,确实挺好用,自建题库,全程自助. 可以插入文字.图片.音频,会安排合理的复习频率,可以随时同步,电脑手机版本全.