暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Elasticsearch-nested类型适用场景

原创 1727 2023-08-28
1348

Snipaste_20231227_101648.png

最近生产Elasticsearch中用到嵌套类型,同时还发现一些小坑,跟大家做个简单的分享。

关于ES中的嵌套类型:

  • 官方释义:nested类型是object一种数据类型,允许对象数组以互相独立的方式进行索引
  • 适用场景:字段值为复杂类型的情况

案例演示:
数据准备

PUT /test_index/_doc/1
{
“column_1”: “A”,
“column_2”: “B”,
“column_list”: [
{
“list_1”: “aa”,
“list_2”: 1
},
{
“list_1”: “bb”,
“list_2”: 2
},
{
“list_1”: “cc”,
“list_2”: 3
}
]
}


PUT /test_index/_doc/2
{
“column_1”: “A”,
“column_2”: “B”,
“column_list”: [
{
“list_1”: “a”,
“list_2”: 11
},
{
“list_1”: “b”,
“list_2”: 22
},
{
“list_1”: “c”,
“list_2”: 33
}
]
}

假设现在有个需求,要查询test索引中list_1=“aa” 并且 list_2=3的数据。
先预期一下结果,应该没有返回数据才对
写DSL并查看结果

GET test_index/_search
{
“query”: {
“bool”: {
“must”: [
{
“match”: {
“column_list.list_1”: “aa”
}
},
{
“match”: {
“column_list.list_2”: 3
}
}
]
}
}
}

结果惊为天人,居然把“_doc/1”这条数据查出来了
查阅资料后原因如下:
当字段值为复杂数据类型(Object、Geo-Point等)的时候,ES内部实际是以如下方式保存数据的

{
“column_1”: “A”,
“column_2”: “B”,
“column_list.list_1”: [“aa”,“bb”,“cc”],
“column_list.list_2”: [1,2,3]
}

通俗的讲就是ES没有保存对象中的逻辑关系,从而导致无法准确搜索。
解决方案
使用Nested类型
1、创建Mapping

PUT test_index
{
“mappings”: {
“properties”: {
“column_1” :{“type”: “string”},
“column_2” :{“type”: “string”},
“column_list”: {
“type”: “nested”,
“properties”: {
“list_1”: {
“type”: “text”
},
“list_2”: {
“type”: “long”
},
}
}
}
}
}

2、写入数据(同上)
3、相同的查询条件,使用新的查询语句

GET /test/_search
{
“query”: {
“nested”: {
“path”: “column_list”,
“query”: {
“bool”: {
“must”: [
{
“match”: {
“column_list.list_1”: “aa”
}
},
{
“match”: {
“column_list.list_2”: 3
}
}
]
}
}
}
}
}

此时查询结果为理想值,空。

所以遇到对象中多个数组间有逻辑关系时,我们需要使用Nested类型

但是Nested还是有他的弊端
在压测中发现,普通的query查询效率远远高于使用nested查询的效率,特别是nested中存在多个对象时。
所以在业务设计时如果存在此类场景也可以将nested部分单独出一个索引进行使用,从而避免使用nested而引起的查询性能问题。

最后修改时间:2023-12-27 10:27:32
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论