ElasticSearch简介(也称ES)
Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能,还可以进行以下工作:
- 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
- 实时分析的分布式搜索引擎。
- 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。
ElasticSearch数据类型
一级分类 | 二级分类 | 具体类型 |
---|---|---|
基础类型 | 字符串类型 | string,text,keyword |
-- | 整数类型 | integer,long,short,byte |
-- | 逻辑类型 | boolean |
-- | 浮点类型 | double,float,half_float,scaled_float |
-- | 日期类型 | date |
-- | 范围类型 | range |
-- | 二进制类型 | binary |
复合类型 | 数组类型 | array |
-- | 对象类型 | object |
-- | 嵌套类型 | nested |
地理类型 | 地理坐标类型 | geo_point |
-- | 地理地图 | geo_shape |
特殊类型 | IP类型 | ip |
-- | 范围地图 | completion |
-- | 令牌计数类型 | token_count |
-- | 附件地图 | attachment |
-- | 抽取类型 | percolator |
以上便是ES中的数据类型,下面便对其中的object和nested来做一个简单的介绍。
nested介绍
nested就是一个嵌套对象,是object数据类型的特殊版本,它允许对象数组相互独立地进行索引和查询,使用时和其他类型使用基本相同,下面便是我来举的一个例子,labels便是一个nested类型的数据
{
"settings": {
"index": {
"codec": "best_compression",
"mapping": {
"nested_fields": {
"limit": "2000"
},
"total_fields": {
"limit": "10000"
}
},
"refresh_interval": "1s",
"number_of_shards": "2",
"translog": {
"flush_threshold_size": "1gb",
"sync_interval": "30s",
"durability": "async"
},
"number_of_replicas": "1"
}
},
"mappings": {
"dynamic": true,
"properties": {
"id": {
"type": "long",
"doc_values": false,
"index": false
},
"name": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"provinces": {
"type": "keyword",
"doc_values": false
},
"city": {
"type": "keyword"
},
"permissionLevel": {
"type": "integer",
"doc_values": false,
"index": false
},
"status": {
"type": "integer"
},
"labels": {
"type": "nested",
"properties": {
"label": {
"type": "keyword"
},
"classification": {
"type": "keyword"
}
}
}
}
}
}
当需要使用这个嵌套类型中的数据进行过滤,统计时我们普遍会使用这个来做一个聚合查询,但是这个会出现一个问题,那便是,所聚合出来的数据只是nested对象的数据,而外部主体数据并没有聚合出来那便是一个问题
{
"size": 0,
"query": {
"bool": {
"must": [
{
"nested": {
"path": "labels",
"query": {
"term": {
"labels.classification": "行业"
}
}
}
}
]
}
},
"aggs": {
"genres": {
"nested": {
"path": "labels"
},
"aggs": {
"label_agg": {
"terms": {
"field": "labels.label"
},
"aggs": {
"count_sub": {
"sum": {
"field": "viewCpount"
}
}
}
},
"fll": {
"filter": {
"term": {
"labels.classification": "行业"
}
},
"aggs": {
"label_agg2": {
"terms": {
"field": "labels.label"
}
}
}
}
}
}
}
}
之后,通过对官网文档,还有同事的讨论,当对nested对象使用聚合查询时,便需要时用reverse_nested,来回到root主体。这样便能够对nested之外的数据来进行聚合操作了。
{
"size": 0,
"query": {
"bool": {
"must": [
{
"nested": {
"path": "labels",
"query": {
"term": {
"labels.classification": "c1"
}
}
}
}
]
}
},
"aggs": {
"genres": {
"nested": {
"path": "labels"
},
"aggs": {
"fll": {
"filter": {
"term": {
"labels.classification": "c1"
}
},
"aggs": {
"label_agg2": {
"terms": {
"field": "labels.label"
},
"aggs": {
"res": {
"reverse_nested": {},
"aggs": {
"count_view": {
"sum": {
"field": "viewCount"
}
}
}
}
}
}
}
}
}
}
}
}```