数组如何在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 构建 ...
随机推荐
- python基础 - 切片
今日学习内容 切片 取一个list或者tuple的部分数据是常见的操作 a = [1,2,3] 比如取第一个数我们可以用a[0]的方式,如果我们想取第一个和第二个就有点困难了,a[0-1]或者a[0] ...
- AS报错:gradle project sync failed
情形一: Android studio下突然报错: gradle project sync failed.Basic functionality(e.g.editing,debugging) will ...
- Kubernetes 多集群在开源项目 KubeSphere 的应用
Kubernetes 多集群使用场景 随着容器的普及和 Kubernetes 的日渐成熟,企业内部运行多个 Kubernetes 集群已变得颇为常见.概括起来,多个集群的使用场景主要有以下几种. 多集 ...
- 操作系统-PV习题
(1)阅览室问题:加入阅览室入口有一本登记册,每个人都必须按顺序签名进去. 想法:登记册可以用结构数组A[]表示,包含name和number.此外,还需要信号量seatcount表示剩余座位数. 使用 ...
- Java数据结构——循环链表
一.单向循环链表表中的最后一个节点的指针域指向头结点,整个链表形成一个环.其他的与单链表相同. (以下图片均来自网络,侵删) 插入操作 删除操作 简单实现 public class CiNode { ...
- laravel核心Ioc容器
laravel容器和依赖注入 啥是Ioc容器,方便我们实现依赖注入的一种实现,也就是说依赖注入不一定需要控制反转容器,只不过使用容器可能会方便些. laravel通过向容器中绑定接口的具体实现,可实现 ...
- 【小白学PyTorch】4 构建模型三要素与权重初始化
文章目录: 目录 1 模型三要素 2 参数初始化 3 完整运行代码 4 尺寸计算与参数计算 1 模型三要素 三要素其实很简单 必须要继承nn.Module这个类,要让PyTorch知道这个类是一个Mo ...
- android开发之动画的详解 整理资料 Android开发程序小冰整理
/** * 作者:David Zheng on 2015/11/7 15:38 * * 网站:http://www.93sec.cc * * 微博:http://weibo.com/mcxiaob ...
- iview table render 进阶(一)
Qestion: 如何给表格添加hover 事件? step1: 添加 domProps 选项参数 step2: 废话不多说,直接看demo code render: (h, params) =& ...
- Unity 深度冲突的解决方法
Dillon|2014-02-12 10:00|5899次浏览|Unity(280)0 3d游戏中当2个片元距离近裁减平面 w 落在同一个区间的时候,他们的深度是相等的. 最终你所看到的结果,就是下 ...