1:es简介
es是一个分布式的搜索引擎,使用java开发,底层使用lucene。
特点:天生支持分布式的、为大数据而生的。基于restful接口。
2:es和solr对比
接口
solr:类似webservice的接口
es:REST风格的访问接口
分布式存储
solrCloud solr4.x才支持
es是为分布式而生的
支持的格式
solr xml json
es json
近实时搜索
都可以实现近实时搜索
3:es和mysql对比
mysql中有database(数据库)。
es中有index(索引库)。
mysql中有table(表)。
es中有type(类型)
mysql中有row(行)
es中有document(文档)
mysql中有column(列)
es中有field(字段/属性)
在es中可以有很多index索引库,每个index索引库可以有很多的type类型,
每一个type类型下面会有很多的document文档,
每一个文档会有很多field字段或者属性组成。
4:es安装,启动
下载、解压
cd /usr/local
tar -zxvf elasticsearch-1.4.4.tar.gz
cd elasticsearch-1.4.4/
bin/elasticsearch
这样就可以在前台启动了
访问:http://ip:9200
如何在后台运行
bin/elasticsearch -d
但是这样在后台运行,停止的话只能使用kill命令,所以是不合理的。
一般想要在后台运行es,都会使用一个插件实现
到github上下载插件,下载一个zip包
地址:https://github.com/elastic/elasticsearch-servicewrapper
解压插件
cd /usr/local
unzip elasticsearch-servicewrapper-master.zip
cd elasticsearch-servicewrapper-master
cp -r service ../elasticsearch-1.4.4/bin/
把serveice目录拷贝到es的bin目录下面之后就可以使用这个插件启动了
启动:bin/service/elasticsearc start
停止:bin/service/elasticsearc stop
重启:bin/service/elasticsearc restart
5:使用curl操作es
注意:在指定索引库的名称时,索引库名称必须要全部小写,不能以下划线开头,也不能包含逗号
1):添加数据
指定ID
curl -XPOST http://localhost:9200/crxy/emp/1 -d '{"name":"zs1","age":18}'
curl -XPUT http://localhost:9200/crxy/emp/1 -d '{"name":"zs2","age":18}'
不指定ID,只能使用POST
curl -XPOST http://localhost:9200/crxy/emp -d '{"name":"zs3","age":18}'
2):查询
通过ID查
curl -XGET http://localhost:9200/crxy/emp/1
通过search查
curl -XGET http://localhost:9200/crxy/emp/_search
根据查询条件查
curl -XGET http://localhost:9200/crxy/emp/_search?q=name:zs1
通过mget查询
curl -XGET http://localhost:9200/crxy/emp/_mget -d {"docs":[{"_id":1,"_source":"name"},{"_index":"crxy","_type":"emp","_id":2}]}
curl -XGET http://localhost:9200/crxy/emp/_mget?pretty -d '{"ids":["1","2"]}'
3):更新
可以使用put或者post可以实现更新(直接覆盖了)
内部更新流程
注意:执行更新操作的时候
ES首先将旧的文档标记为删除状态
然后添加新的文档
旧的文档不会立即消失,但是你也无法访问
ES会在你继续添加更多数据的时候在后台清理已经标记为删除状态的文档
局部更新
只能使用post
curl -XPOST http://localhost:9200/crxy/emp/1/_update -d '{"doc":{"name":"aaa"}}'
4):删除
可以通过ID删除
curl -XDELETE http://localhost:9200/crxy/emp/4/
通过查询条件删除
curl -XDELETE 'http://localhost:9200/crxy/emp/_query?q=name:zs'
curl -XDELETE 'http://localhost:9200/crxy/emp,user/_query?q=name:zs'
curl -XDELETE 'http://localhost:9200/crxy,crxy1/emp,user/_query?q=name:zs'
curl -XDELETE 'http://localhost:9200/_all/_query?q=name:zs'
5):批量操作
使用bulk实现
格式如下:注意:不能放在一行。
{ action: { metadata }}
{ request body }
{ action: { metadata }}
{ request body }
action可以使用这几个值:index/create/update/delete
metadata可以使用这几个值:_index,_type,_id
request body需要指定要操作的属性:_source(删除操作不需要)
例子:
创建一个文件,把下面的内容拷贝进去,做相应的修改
cd /usr/local/
vi request
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "1" } }
{ "field1" : "value1" }
{ "create" : { "_index" : "test", "_type" : "type1", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_type" : "type1", "_index" : "index1"} }
{ "doc" : {"field2" : "value2"} }
{ "delete" : { "_index" : "test", "_type" : "type1", "_id" : "2" } }
执行命令(在bulk之前还可以指定索引库和类型。那么对应的文件中的这些属性,相同的就可以省略了、)
curl -XPOST/PUT localhost:9200/_bulk --data-binary @request
注意:create和index命令的不同,如果索引库中有对应的数据,使用create则创建失败,使用index则创建成功。
bulk一次最大处理多少数据量
bulk会把将要处理的数据载入内存中,所以数据量是有限制的
最佳的数据量不是一个确定的数值,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载
一般建议是1000-5000个文档,如果你的文档很大,可以适当减少队列,大小建议是5-15MB,默认不能超过100M,
可以在es的配置文件中修改这个值http.max_content_length: 100mb
6:版本控制
默认es使用乐观控制,也就是说不限制任何进程同时操作同一条数据。
我们可以通过版本号来控制,保证在并发情况下的数据安全。
1)使用内部版本号,这样就需要保证我们传递的版本号要和索引库中的版本号一致。
首先得到需要修改的文档,获取版本(_version)号
curl -XGET http://localhost:9200/crxy/emp/1
在执行更新操作的时候把版本号传过去
curl -XPUT http://localhost:9200/crxy/emp/1?version=1 -d '{"name":"crxy","age":25}'(覆盖)
curl -XPOST http://localhost:9200/crxy/emp/1/_update?version=1 -d '{"doc":{"city":"beijing","car":"BMW"}}'(部分更新)
2)使用外部版本号:这样就需要保证我们传递的外部版本号要比索引库中的版本号大才能执行更新。
并且外部版本号码必须要是大于0小于9223372036854775807(Java中long的最大正值)的整数。
curl -XPUT 'http://localhost:9200/crxy/emp/20?version=10&version_type=external' -d '{"name": "crxy"}'
注意:此处url前后的引号不能省略,否则执行的时候会报错
——————————————————————————————————————————————————————————————————————
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
————————————————————————————————————————————————————————————————————————
1:es中安装插件
bin/plugins -install 插件名称
安装完成之后在ES的根目录下面会生成一个plugins目录,里面存放的就是安装的插件
具体的插件名称需要到github上查找
例如:bigdesk
执行下面搜索
https://github.com/search?utf8=%E2%9C%93&q=bigdesk
一般是找后面五角星中值比较大的那个,选择对应的项目名称即可,lukas-vlcek/bigdesk
这样就可以在es中进行安装了
bin/plugins -install lukas-vlcek/bigdesk
访问插件
http://ip:9200/_plugin/bigdesk
2:es的配置文件讲解
参考文件<elasticsearch中文.yml>
3:es中的核心概念
集群:
针对es而言是在集群中有主从节点,对于外部使用人员而言,已经弱化了主从节点这个概念。
默认情况下,一个内网之内的多个es实例会自动组成一个es集群。
分片:
默认情况下,es中的一个索引库会有五个分片,这个数量在配置文件中可以修改,
具体属性名称为:index.number_of_shards
注意:索引库的分片数量在创建索引库之前就需要定义好,索引库创建之后就不能修改了。
可以通过下面这种方式来实现在创建索引库的时候指定分片的数量
curl -XPUT 'localhost:9200/test1/' -d'{"settings":{"number_of_shards":3}}'
副本:
默认情况下,一个分片会有一个副本,这个数量在配置文件中可以修改,
具体属性名称为:index.number_of_replicas
注意:副本数量可以随时修改。
可以通过下面命令进行修改
curl -XPUT 'localhost:9200/test2/' -d'{"settings":{"number_of_replicas":2}}'
数据重新分布机制
当es集群中新增或者删除节点的时候,会根据每个节点的负载重新对集群中的分片进行分配。
数据持久化方式
默认es中的索引文件是存储在本地的。还可以存储到分布式文件系统中,例如:hdfs
自动发现机制
es默认会把一个网段内的es实例组成一个集群,是通过多播协议,把一个网段之内的节点组成集群。
如何把不同网段的es实例组成一个es集群(修改ES_HOME/conf/elasticsearch.yml文件)
1:首先禁用自动发现机制
discovery.zen.ping.multicast.enabled: false
2:给新启动的节点指定能够发现的主节点的IP,在这可以指定IP,也可以指定IP+端口,
如果端口是默认值9300的话,可以省略。
discovery.zen.ping.unicast.hosts: ["10.11.52.131", "10.11.52.134:9300"]
通信协议
默认es各个节点之间通信是使用9300端口,使用http方式访问es的话需要使用9200端口
4:通过java代码操作es
首先需要添加es的maven依赖
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>1.4.4</version>
</dependency>
在建立索引的时候,如果使用了bean(对象)的方式,需要添加下面的依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.1.3</version>
</dependency>
具体的增删改查参考<EsTest.java>
查询类型-searchType
query_then_fetch:
默认es使用query_then_fetch,这种方式返回的数据量是正确的,但是,数据的相关性可能不是最准确的。
query_and_fetch
这种查询类型执行的速度是最快的,但是,返回的数据可能是需要的N倍,并且返回的数据相关性也不准确
dfs_query_then_fetch
这种查询速度相对来说是最慢的一个,但是,返回的数据量和数据相关性是最高的。
dfs_query_and_fetch
这种查询返回的数据量可能是需要的N倍,但是数据的相关性是准确的。
dfs:表示初始化散发的意思
具体意思就是在查询之前会多一个收集词频和文档频率的过程。这样可以保证查询的数据相关性是最高的。
总结一下,
从性能考虑QUERY_AND_FETCH是最快的,DFS_QUERY_THEN_FETCH是最慢的。
从搜索的准确度来说,DFS要比非DFS的准确度更高。
es的查询操作
主要是分页,排序,过滤,高亮,统计
这些参考代码<EsTest.java>