前言:
之前已经说过最近正在做数据建设,爬取数据之后经过处理,最终导入到ElasticSearch中,并编写公共接口以提供给后台进行检索操作;本来想等把ElasticSearch官方API都看过一遍,形成思维导图之后再整理出来,因为熟悉一个工具,它能做到的,比你知道它能做到的要全面也重要的多,但是整理了两章之后发现,内容真的太多了,这还仅仅只2类。。所以想还是先把基础用法记录下来,先一步步来了。
ElasticSearch 简介
Elasticsearch 是一个分布式可扩展的近实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能,还可以进行以下工作:
- 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
- 实时分析的分布式搜索引擎。
- 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。
ElasticSearch 安装
安装比较简单,建议练手阶段安装Kibana,安装步骤参见之前写的博客:ElasticSearch安装
基本概念:
- ES是一个近实时的搜索引擎,面向文档型数据库,一条数据就对应一个文档,以JSON格式存储;
- 所有的操作都是通过rest接口实现,即每一个操作都是向ES发送要给rest请求
- 支持分布式部署,node节点跟slave集群;
- shards分片:个人感觉类似于关系型数据库的分区分表操作
- replicas副本:类似于传统数据库的从表了,ES里是针对每个shards而言的副本
例如:创建index默认为shards为5,replicas为1,则意味着总共有10个shards,5个主5个从; - 与传统关系型数据库术语对照表如下:
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 文档(Docments) ⇒ 字段(Fields)
- 6.x之后ES建议删除type,因为按照目前理解的type=table,但实际上却并不太一样,ES里同一个index下的多个type字段类型必须一致;但是传统数据库中,一个db里的多个table是可以不一样的;
具体可看官网:删除type及替代方案
目前6.x语法上也还是支持type,7.x语法就不支持了,所以要习惯理解修改后的模式:
Elasticsearch ⇒ 索引(Index) ⇒ 文档(Docments) ⇒ 字段(Fields)
创建Index(索引)
既然删除了type,感觉将Index理解为table是不是更加合理些。。
创建Index语法如下:
PUT /userinfo?pretty
{
"mappings": {
"_doc": {
"properties": {
"name": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word", "fields": {"raw":{"type":"keyword"}}},
"content": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" },
"org_type": { "type": "keyword"},
"create_time":{"type":"date", "format": "epoch_second"}
}
}
}
}
如果理解了上面的基本概念的话,这命令看起来应该不难理解,有几点需要提一下:
-
analyzer、search_analyzer:为该字段配置的分词器,
- 中文一般使用ik分词器 包括ik_max_word和ik_smart,ik_max_word:会将文本做最细粒度的拆分;尽可能多的拆分出词语 ,ik_smart:会做最粗粒度的拆分;已被分出的词语将不会再次被其它词语占有
- type为text的不支持排序,统计等操作,如有排序或统计需求,则需在后面加上"fields": {"raw":{"type":"keyword"}}以支持该功能,text 类型的字段,如不指定分词器,ES会默认设置分词器
- type为date可以指定转换格式,epoch_second转换为当前时间的秒数
这只是简单常用的创建Index的命令,完整的请点击Mapping API - ES会根据值自动创建映射,例如,给usetinfo新增一个age字段,可以直接添加即可:
通过GET /userinfo/_mapping命令查看userinfo最新的字段,可以看到ES默认新增了一个类型为long的age字段。但是一般建议关键字段在创建Index的时候进行指定字段;PUT /userinfo/_doc/1? { "name":"lctest", "age":29 }
{ "userinfo": { "mappings": { "_doc": { "properties": { "age": { "type": "long" }, "content": { "type": "text", "analyzer": "ik_max_word" }, "create_time": { "type": "date", "format": "epoch_second" }, "name": { "type": "text", "fields": { "raw": { "type": "keyword" } }, "analyzer": "ik_max_word" }, "org_type": { "type": "keyword" } } } } } }
修改Index
- ES不支持对索引中已有的字段进行修改,只能添加字段,添加字段有两种方法,
- 上面提到的,直接赋值,由ES去创建字段;
- 手动设置字段,代码如下:
PUT /userinfo/_mapping/_doc { "properties": { "params": { "type": "nested", "properties": { "update_time":{"type":"date", "format": "epoch_second"} } } } }
删除Index
//删除指定索引
DELETE /userinfo
//删除多个索引
DELETE /index1,index2 或者 DELETE /index*
//删除所有索引
DELETE /_all 或者 DELETE /*
最基本的索引操作就到此结束,基本上能满足简单的基本需求,下面有一些扩展知识点,可以选择性的使用
aliases别名
索引别名就像一个快捷方式或软连接,或者是一个指向,都是最终指的同一个东西,别名 带给我们极大的灵活性,允许我们做下面这些:
- 在运行的集群中可以无缝的从一个索引切换到另一个索引
- 给多个索引分组 (例如, last_three_months)
- 给索引的一个子集创建 视图
有两种方式管理别名: _alias用于单个操作, _aliases用于执行多个原子级操作。- 创建别名
POST /_aliases { "actions" : [ { "add" : { "index" : "test1", "alias" : "alias1" } } ] }
- 删除别名
POST /_aliases { "actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } } ] }
- 切换索引
POST /_aliases { "actions" : [ { "remove" : { "index" : "test1", "alias" : "alias1" } }, { "add" : { "index" : "test2", "alias" : "alias1" } } ] }
- 操作单个索引
PUT /{index}/_alias/{name} PUT /logs_201305/_alias/2013
以上便是Index别名的基本常用语法,完整API详见Aliases API
常用命令
查看所有索引信息 GET /_cat/indices?v&pretty
查看某个索引信息 GET /{index}
删除索引单个索引 DELETE /{index}
删除所有索引 DELETE /_all 或者 DELETE /*
删除多个索引: DELETE /index1,index2 或者 DELETE /index*
查看索引的映射 GET /{index}/_mapping
查看某个索引的某个类型的映射 GET /{index}/_mapping/{type}
映射添加新字段 PUT /{index}/_mapping/{type}
禁用通配符
为了防止误操作 ,造成删库跑路的情况,建议在elasticsearch.yml 做如下配置:action.destructive_requires_name: true 这个设置使删除只限于特定名称指向的数据, 而不允许通过指定 _all 或通配符来删除指定索引库。你同样可以通过 Cluster State API 动态的更新这个设置。
新手推荐使用Kibana工具,带命令提示,很适合不熟悉命令的初学者,我也一直在用,只是博客的话,命令的表现形式感觉更好一些