ElasticSearch的认识
ElasticSearch简称ES,用于对海量的数据进行近实时的处理。ES的索引库管理支持依然是基于Apache Lucene™的开源搜索引擎。说白了就是对Lucene进行了进一步的封装和功能的扩展优化。它的目的是通过简单的 RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
不过,ES的核心不在于Lucene,其特点更多的体现为:
1.分布式的实时文件存储,每个字段都被索引并可被搜索
2.分布式的实时分析搜索引擎
3.可以扩展到上百台服务器,处理PB级结构化或非结构化数据
4.高度集成化的服务,你的应用可以通过简单的 RESTful API、各种语言的客户端甚至命令行与之交互。
5.上手Elasticsearch非常容易。它提供了许多合理的缺省值,并对初学者隐藏了复杂的搜索引擎理论。它拥有开瓶即饮的效果(安装即可使用),只需很少的学习既可在生产环境中使用。
安装ElasticSearch
ES服务只依赖于JDK,推荐使用JDK1.7+。
ES官方下载地址:https://www.elastic.co/downloads/elasticsearch
运行ES,bin目录下的elasticsearch.bat文件
验证ES的正常启动
在浏览器访问http://localhost:9200/
在本机测试的时候如果本机内存过小或磁盘空间过小会启动失败;可以在config中的jvm.options文件中修改参数
ES和所有客户端的交互方式
① 基于RESTful API
ES和所有客户端的交互都是使用JSON格式的数据. 其他所有程序语言都可以使用RESTful API,通过9200端口的与ES进行通信,在开发测试阶段,你可以使用你喜欢的WEB客户端, curl命令以及火狐的POSTER插件方式和ES通信。 Curl命令方式: 默认windows下不支持curl命令。
② Java API
ES为Java用户提供了两种内置客户端:
节点客户端(node client):
节点客户端以无数据节点(none data node)身份加入集群,换言之,它自己不存储任何数据,但是它知道数据在集群中的具体位置,并且能够直接转发请求到对应的节点上。
传输客户端(Transport client):
这个更轻量的传输客户端能够发送请求到远程集群。它自己不加入集群,只是简单转发请求给集群中的节点。
两个Java客户端都通过9300端口与集群交互,使用ES传输协议(ES Transport Protocol)。集群中的节点
之间也通过9300端口进行通信。如果此端口未开放,你的节点将不能组成集群。
注意
Java客户端所在的ES版本必须与集群中其他节点一致,否则,它们可能互相无法识别。
ES文档的基本格式
ES是面向文档的,他可以储存整个对象或者文档,还可以索引每个文档的内容,可以让你对文档进行索引,排序,搜索,过滤操作。ES使用的是JSON格式存储文档
ES具体的储存文档示例:
{
_index : “crm”,
_type : “user”,
_id : 1,
_source : {
"email": "nxh@itsource.cn",
"name": "谢三哥",
"info": {
"addr": "四川省成都市",
"age": 30,
"hobbys": [ "美食", "美女" ]
},
"join_date": "2018-11-01"
}
}
ES集群可以包含多个索引(indices)(数据库),每一个索引库中可以包含多个类型(types)(表),每一个类型包含多个文档(documents)(行),然后每个文档包含多个字段(Fields)(列)。
_source:文档原始数据
_index索引库相当于关系型数据库里面的“数据库”
使用客户端辅助工具进行实操
这里使用客户端辅助管理工具Kibana5
Kibana5.2.2下载地址:https://www.elastic.co/downloads/kibana
启动Kibana5 : bin\kibana.bat
在浏览器中默认访问地址:http://localhost:5601进入如下页面
一、创建索引库
#创建索引库
PUT crm
响应如下表示创建成功
{
"acknowledged": true,
"shards_acknowledged": true
}
响应的我们也可以对改索引库进行查询和修改
#查询索引库
GET crm
#删除索引库
DELETE crm
二、添加文档
在该索引库中创建文档,储存的文档的id可以自己写,也可以使用ES自动生成。
#向索引库中添加文档
POST crm/user/1
{
"name":"谢三哥",
"color":"red",
"salary":10000
}
三、查询索引库文档
添加文档之后crm库中就会存在该文档,之后就可以查询该文档。
在知道文档id的情况下查询
#在知道文档id的情况下查询
GET crm/user/1?pretty
查询结果响应,直接就是你添加的文档的内容
{
"_index": "crm",
"_type": "user",
"_id": "1",
"_score": 1,
"_source": {
"name": "谢三哥",
"color": "red",
"salary": 10000
}
在不知道文档id的情况下查询
#在不知道文档id的情况下查询
GET crm/user/_search
响应如下
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "crm",
"_type": "user",
"_id": "2",
"_score": 1,
"_source": {
"name": "谢三哥",
"color": "red",
"salary": 10000
}
}
]
}
}
四、修改文档
①更新整个文档
#更新整个文档
PUT crm/user/1
{
"salary":10001,
"age":18
}
执行过后可以看见有一行响应是 “created”: false;因为同索引、同类型下已经存在同ID的文档。,Elasticsearch已经标记旧文档为删除并添加了一个完整的新文档。旧版本文档不会立即消失,但你也不能去访问它。Elasticsearch会在你继续索引更多数据时清理被删除的文档。但版本确实更新了可以看到 响应 “_version”: 2, 版本增加了。注意的更新其实是ES先删除再进行了添加
②局部更新文档
局部更新文档,之前的属性有的就进行更改,没有的会进行新增,版本不会变
#局部更新表
POST crm/user/1/_update
{
"doc":{
"color":"bule",
"name":"Jerry"
}
}
五、删除文档
#删除表
DELETE crm/user/1
DSL查询与过滤
ES提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。
使用DSL查询,必须要传递query参数给ES。
DSL查询
查询公司员工性别为女的员工,并按照加入时间降序、年龄升序排列(只返回名字、年龄和email字段)
GET itsource/employee/_search
{
"query": {
"match": {"sex":"女"}
},
"from": 0,
"size": 10,
" _source": ["fullName", "age", "email"],
"sort": [{"join_date": "desc"},{"age": "asc"}
}
DSL过滤
DSL过滤查询文档的方式更像是对于我的条件“有”或者“没有”,而DSL查询语句则像是“有多像”。
DSL过滤和DSL查询在性能上的区别:
1.过滤结果可以缓存并应用到后续请求。
2.查询语句同时匹配文档,计算相关性,所以更耗时,且不缓存。
3.过滤语句可有效地配合查询语句完成文档过滤。
{
"query": {
"bool": {
"must": [
{"match": {"description": "search" }}
],
"filter": {
"term": {"tags": "lucene"}
}
}
}
}
match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。
match一般只用于全文字段的匹配与查询,一般不用于过滤。
组合条件搜索与过滤(Bool)
组合搜索bool可以组合多个查询条件为一个查询对象,查询条件包括must、should和must_not。
例如:查询爱好有美女,同时也有喜欢游戏或运动,且出生于1990-06-30及之后的人。
{
"query": {
"bool": {
"must": [{"term": {"hobby": "美女"}}],
"should": [{"term": {"hobby": "游戏"}},
{"term": {"hobby": "运动"}}
],
"must_not": [
{"range" :{"birth_date":{"lt": "1990-06-30"}}}
],
"minimum_should_match": 1
}
}
}
bool表示复杂组合查询
must表示必须匹配的条件
should表示也可能匹配的条件
“minimum_should_match”: 1 表示至少匹配的个数
term 单词的匹配
range 范围查询
注意:
如果 bool 查询下没有must子句,那至少应该有一个should子句。但是 如果有 must子句,那么没有 should子句也可以进行查询。
前匹配搜索与过滤(prefix)
和term查询相似,前匹配搜索不是精确匹配,而是类似于SQL中的like ‘key%’
查询姓谢的
{
"query": {
"prefix": {
"name": "谢"
}
}
}