在使用ES保存数据时,大部分时间都会把数据直接按JSON数据平铺保存,但是这样会存在一个问题:对象内部数据之间的关联会丢失。
示例数据有两条data_1和data_2,每条数据里面会有一个对象list:
data_1
{
"logs":[
{
"name":"test1",
"error_type":1,
},
{
"name":"test2",
"error_type":2,
},
{
"name":"test3",
"error_type":3,
},
{
"name":"test4",
"error_type":0,
},
{
"name":"test5",
"error_type":0,
}
]
}
,
data_2
{
"logs":[
{
"name":"test1",
"error_type":1,
},
{
"name":"test2",
"error_type":2,
},
{
"name":"test3",
"error_type":3,
},
{
"name":"test4",
"error_type":0,
},
{
"name":"test5",
"error_type":0,
}
]
}
复制
如果将数据做为JSON保存,那么里面的logs会存储为字符串数组:
logs.name: ["test1","test2","test3","test4","test5"]
logs.error_type: [1,2,3,0]
这样在查询的时候所有的数据都会输出,无法正确分组:
{
"aggs": {
"logs_name": {
"terms": {
"field": "logs.name",
"size": 2147483647
},
"aggs": {
"logs_error_type": {
"terms": {
"field": "logs.error_type",
"size": 2147483647
}
}
}
}
}
}
复制
结果不贴出了,本地无法跑。
如果需要对对象list内容进行分组统计就需要使用nested对象,在新建es索引时指定好字段的数据类型为nested对象即可。
mappings = {
"mappings": {
"log_v1":{
"properties": {
"logs": {
"type": "nested" ,
"properties": {
"error_type": { "type": "short" },
"name": { "type": "keyword"} }
}
}
}
}
}
res = es.indices.create(index = 'log_v1',body =mappings)
# 这儿使用的python操作es的库是elasticsearch
复制
然后使用logstash导入数据时会将logs保存为nested object。
查询时使用nested对象查询,查询时指定要查询的nested对象,其余的就和普通查询一样了。
{
"aggs":{
"all_data":{
"nested": {
"path": “logs"
}
},
"aggs":{
"logs_name": {
"terms": {
"field": "logs.name",
"size": 2147483647
},
"aggs": {
"logs_error_type": {
"terms": {
"field": "logs.error_type",
"size": 2147483647
}
}
}
}
}
}}
复制
文章转载自晨起临风,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。