|
ES的基本概念:
基本概念
先说Elasticsearch的文件存储,Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式,比如下面这条用户数据:
{
"name" : "John",
"sex" : "Male",
"age" : 25,
"birthDate": "1990/05/01",
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
用Mysql这样的数据库存储就会容易想到建立一张User表,有balabala的字段等,在Elasticsearch里这就是一个文档,当然这个文档会属于一个User的类型,各种各样的类型存在于一个索引当中。这里有一份简易的将Elasticsearch和关系型数据术语对照表:
关系数据库 数据库 表 行 列(Columns)
Elasticsearch 索引(Index) 类型(type) 文档(Docments) 字段(Fields)
一个 Elasticsearch 集群可以包含多个索引(数据库),也就是说其中包含了很多类型(表)。这些类型中包含了很多的文档(行),然后每个文档中又包含了很多的字段(列)。Elasticsearch的交互,可以使用Java API,也可以直接使用HTTP的Restful API方式,比如我们打算插入一条记录,可以简单发送一个HTTP的请求:
PUT /megacorp/employee/1
{
"name" : "John",
"sex" : "Male",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
索引
Elasticsearch是如何做到快速索引的
InfoQ那篇文章里说Elasticsearch使用的倒排索引比关系型数据库的B-Tree索引快,为什么呢?
什么是B-Tree索引?
二叉树查找效率是logN,同时插入新的节点不必移动全部节点,所以用树型结构存储索引,能同时兼顾插入和查询的性能。因此在这个基础上,再结合磁盘的读取特性(顺序读/随机读),传统关系型数据库采用了B-Tree/B+Tree这样的数据结构:
为了提高查询的效率,减少磁盘寻道次数,将多个值作为一个数组通过连续区间存放,一次寻道读取多个数据,同时也降低树的高度。
什么是倒排索引?
继续上面的例子,假设有这么几条数据(为了简单,去掉about, interests这两个field):
| ID | Name | Age | Sex |
| -- |:------------:| -----:| -----:|
| 1 | Kate | 24 | Female
| 2 | John | 24 | Male
| 3 | Bill | 29 | Male
ID是Elasticsearch自建的文档id,那么Elasticsearch建立的索引如下:
Name:
| Term | Posting List |
| -- |:----:|
| Kate | 1 |
| John | 2 |
| Bill | 3 |
Age:
| Term | Posting List |
| -- |:----:|
| 24 | [1,2] |
| 29 | 3 |
-----------------------------------------------------------ES实际应用----------------------------------------------------------------------------------------------
ES的基本操作:(新建,增,删,改,查) 1.创建索引:(以饱和度算法模型为例子:这个是我做的项目名字) PUT /clue_strategies_clue_saturation/ { "mappings": { "clue_saturation": { "properties": { "uid": { "type": "integer" }, "status": { "type": "integer" }, "saturation_cnt":{ "type":"integer" }, "dt": { "type": "keyword" } } } } }
2.查询索引: GET /clue_strategies_clue_saturation/clue_saturation/_mapping?pretty
3.删除索引:
DELETE /clue_strategies_clue_saturation/
3.1删除ES中指定条件的数据
删除指定条件数据: POST /clue_strategies_clue_saturation/_delete_by_query { "query": { "match": { "dt": "2019-09-02" } } }
4.新增数据: POST /clue_strategies_clue_saturation/clue_saturation/ { "uid":1, "status":1, "saturation_cnt ":10, "dt":"2019-07-23" }
5.查询数据:
5.1 时间范围查询:(查询7月25日的数据) POST /clue_strategies_clue_saturation/clue_saturation/_search?pretty {
"size": 5600,
"query": {
"range": {
"dt": {
"lt": "2019-07-26", --小于
"gte": "2019-07-25" --大于等于
}
}
}}
5.2 排序查询:(按状态降序查询)
POST /clue_strategies_clue_saturation/clue_saturation/_search?pretty {
"query": { "match_all": {} },
"sort": { "status": { "order": "desc" } }
}
5.3 查询指定列:
POST /clue_strategies_clue_saturation/clue_saturation/_search?pretty {
"query": { "match_all": {} },
"_source": ["status", "saturation_cnt"]
}
5.4 带条件查询:(查询状态为8的值)
POST /clue_strategies_clue_saturation/clue_saturation/_search?pretty {
"query": { "match": { "status": 8} }
} 6.遇到的问题:
字段类型不同:int ES报错:版本问题 改为:integer
decimal(10,5) 与 string ES有数据,hive查询会报错 解决变为hive 变为string ES变为keyword
decimal(10,5) 与 double 也不行
支持建唯一索引
没数据报错:加上 'es.index.read.missing.as.empty'='true'
7.饱和度建表:
-------饱和度建表 CREATE TABLE `features.app_sale_clue_status_saturation_result_es`( uid int COMMENT '学规ID', status int COMMENT '线索状态', saturation_cnt int COMMENT '饱和度', dt string COMMENT '日期' ) COMMENT '学规线索饱和度(学规+线索状态粒度)' STORED BY 'org.elasticsearch.hadoop.hive.EsStorageHandler' TBLPROPERTIES ( 'es.index.auto.create'='false', 'es.index.read.missing.as.empty'='true', --防止查询为空值报错 'es.mapping.names'='uid:uid,status:status,saturation_cnt:saturation_cnt,dt:dt', --hive字段对应的ES字段 'es.net.http.auth.pass'='ES密码', --ES密码 'es.net.http.auth.user'='ES登录名', --ES登录名 'es.nodes'='es-cn-0pp165u620001xs3r.elasticsearch.aliyuncs.com', --ES地址 'es.nodes.wan.only'='true', 'es.nodes.discovery' = 'false', 'es.port'='9200', 'es.read.metadata'='true', 'es.resource'='clue_strategies_clue_saturation/clue_saturation' --ES中索引 ) |