1.前言
项目中需要对较大量的数据进行搜索和分析,所以就E对lasticSearch进行研究在这记录一下.
2.ElasticSearch是什么?
是一个高可用开源全文检索和分析组件。提供存储服务,搜索服务,大数据准实时分析等。一般用于提供一些提供复杂搜索的应用。基于Lucene的搜索服务器(是一个基于 lucence 可水平扩展的自动化近实时全文搜索服务组件)。
基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。
Elasticsearch官网:https://www.elastic.co/cn/products/elasticsearch
它的特点是:
1)准实时的搜索工具,在一般情况下延时少于一秒
2)分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心)
3)Restful风格,一切API都遵循Rest原则,容易上手
4)近实时搜索,数据更新在Elasticsearch中几乎是完全同步的。
搜索按照功能又分为垂直搜索和综合搜索.
垂直搜索是指专门搜索一类的信息. 例如 职友集,爱看图标网等.
综合搜索就是像一些大的互联网公告 百度 谷歌 搜狗 360等.
3.基本概念
Index
定义:类似于mysql中的database。索引只是一个逻辑上的空间,物理上是分为多个文件来管理的。
命名:必须全小写
描述:因为本身ES是基于Lucene的,所以内部索引的本质上其实Lucene的索引构造方式,具体Lucene的 索
引文件具体分为那几个文件,之前我在Lucene部分的有过介绍【http://blog.csdn.net/cfl20121314/article/details/46008203 】。
ES中index可能被分为多个分片【对应物理上的lcenne索引】,在实践过程中每个index都会有一个相应的副
本。主要用来在硬件出现问题时,用来回滚数据的。这也某种程序上,加剧了ES对于内存高要求。
Type
定义:类似于mysql中的table,根据用户需求每个index中可以新建任意数量的type。
Document
定义:对应mysql中的row。有点类似于MongoDB中的文档结构,每个Document是一个json格式的文本。
Mapping
更像是一个用来定义每个字段类型的语义规范在mysql中类似sql语句,在ES中经过包装后,都被封装为友好的Restful风格的接口进行操作。这一点也是为什么开发人员更愿意使用ES或者compass这样的框架而不是直接使用Lucene的一个原因。
Shards & Replicas
定义:能够为每个索引提供水平的扩展以及备份操作。
描述:
Shards:在单个节点中,index的存储始终是有限制,并且随着存储的增大会带来性能的问题。为了解决这个问题,ElasticSearch提供一个能够分割单个index到集群各个节点的功能。你可以在新建这个索引时,手动的定义每个索引分片的数量。
Replicas:在每个node出现宕机或者下线的情况,Replicas能够在该节点下线的同时将副本同时自动分配到其他仍然可用的节点。而且在提供搜索的同时,允许进行扩展节点的数量,在这个期间并不会出现服务终止的情况。
默认情况下,每个索引会分配5个分片,并且对应5个分片副本,同时会出现一个完整的副本【包括5个分配的副本数据】。
4.基本使用
RESTful接口URL的格式:
http://localhost:9200///[]
其中index、type是必须提供的。id是可选的,不提供es会自动生成。index、type将信息进行分层,利于管理。index可以理解为数据库;type理解为数据表;id相当于数据库表中记录的主键,是唯一的。
注:在url网址后面加"?pretty",会让返回结果以工整的方式展示出来,适用所有操作数据类的url。"?"表示引出条件,"pretty"是条件内容。
Elasticsearch http 的操作
获取一个document
curl -X GET http://localhost:9200/index/type/id
获取同一type的所有元素
curl -X GET http://localhost:9200/index/type/_search
新增一个document 可以使用POST或PUT请求
curl -X POST http://localhost:9200/index/type/id -d '
{
"field": "value",
...
}
修改一个document
curl -X PUT http://localhost:9200/index/type/id -d '
{
"field": "value",
...
}
删除一个document
curl -X POST http://localhost:9200/index/type/_search -d '
{
"query": {
...
}
}
注: curl是linux下的http请求,-H "Content-Type: application/json"需要添加,否则会报错{“error”:“Content-Type header [application/x-www-form-urlencoded] is not supported”,“status”:406}
检索操作
curl -X POST http://localhost:9200/index/type/_search -d '
{
"query": {
...
}
}
match_all 匹配所有文档
{
"query": {
"match_all": {
}
}
}
match_none 不匹配任何文档
{
"query": {
"match_none": {
}
}
}
match match中检索的文本会被分词。默认来说分词后各个词组间的关系为or
{
"query": {
"match": {
"message": "hello world"
}
}
}
{
"query": {
"match" : {
"message" : {
"query" : "this is a test",
"operator" : "and"
}
}
}
}
通过增加operator参数,可以把默认的or关系修改为and。
terms
{
"query": {
"terms" : {
"message" : ["some", "text"]}
}
}
查找message字段包含some或text的文档。
Query String 查询
{
"query": {
"query_string" : {
"default_field" : "content",
"query" : "(new york city) OR (big apple)"
}
}
}
将new york city和big apple分别交给分词器处理。
Range Query
范围查询
{
"query": {
"range" : {
"age" : {
"gte" : 10,
"lte" : 20,
"boost" : 2.0
}
}
}
}
可以使用的参数有:
gt: greater than
gte: greater than or equals
lt: less than
lte: less than or equals
Exists
字段存在查询
{
"query": {
"exists" : {
"field" : "user" }
}
}
文档中user字段的值不能为null,user字段必须要存在。
Prefix
前缀查询
{
"query": {
"prefix" : {
"user" : "pe" }
}
}
查找user字段以pe开头的文档(搜索关键字不分词)
wildcard
通配符查询
{
"query": {
"wildcard" : {
"user" : "pa*l" }
}
}
可以匹配paul或paal等。为了保证性能,最好不要在开头使用通配符(比如匹配*aul)。
通配符说明:
星号(*)匹配0个或多个字符
问号(?)匹配任意单个字符
中英文单字(字母)匹配场景
中文模糊搜索
{
"query": {
"match_phrase": {
"name": "公司"
}
}
}
match_phrase 的意思为短语匹配,不仅要匹配短语的字,而且这些字出现的顺序也必须要匹配
英文按字母模糊搜索
{
"query": {
"wildcard": {
"name": "*aster*"
}
}
}
布尔组合条件搜索
通过bool组合查询我们可以实现多个查询条件间and或or逻辑组合关系。例如:
{
"query": {
"bool": {
"should": [
{
"wildcard": {
"name": "*aster*"
}
}, {
"match_phrase": {
"authorList.name": "张"
}
}
]
}
}
}
bool组合查询内有多种子句:
must 子句中的所有匹配必须都满足。
must_not 和must相反,子句中的所有匹配必须都不满足。
should 相当于或的关系,子句中的匹配只要至少有一个满足。如果存在must或filter子句,should中的条件默认不要求至少满足一个,即仅匹配must或filter子句且should中一个条件都不满足的文档也会被检索出来。如需设置至少满足的should条件个数,可以添加minimum_should_match参数。
filter 和must类似,不同的是搜索结果的匹配度评分会被忽略。
minimum_should_match示例:
{
"query": {
"bool": {
"should": [
{
"wildcard": {
"fieldList.fieldName": "*?0*"
}
},
{
"match_phrase": {
"fieldName.fieldComments": "?0"
}
}
],
"filter": [
{
"term": {
"systemId": "?1"
}
}
],
"minimum_should_match": 1
}
}
}
以上查询不仅要求filter语句满足,而且should中的条件至少要满足一个。
Bool查询点击查看更详细的用法
嵌套对象字段的查询
{
“query”: {
“match_phrase”: {
“author.name”: “test book”
}
}
}
检索出author对象中的name字段值为test book的文档。