REST简介:
RSET全称Representational State Transfer。是一种软件的架构风格,而不是标准,只是提供一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制,
其实说白了就是类似HTTP的访问,和HTTP非常的相似。
REST操作:
GET:获取对象的当前状态。
PUT:改变对象的状态。
POST:创建对象。
DELETE:删除对象。
HEAD:获取头信息。
资源 | 一组资源的URI,比如: http://example.com/res/ | 单个资源的URI,比如: http://example.com/res/123 |
GET | 列出URI,以及该资源组中每个资源的详细信息(后者可选) | 获取指定的资源的详细信息,格式可以自选一个合适的网络媒体类型(比如:XML、JSON等) |
PUT | 使用给定的一组资源替换当前整组资源 | 替换/创建指定的资源。并将其追加到相应的资源组中。 |
POST | 在本组资源中创建/追加一个新的资源。该操作往往返回新的URL | 把指定的资源当做一个资源组,并在其下创建/追加一个新的元素,使其隶属于当前资源。 |
DELETE | 删除整组资源 | 删除指定的元素 |
ES内置的REST接口:
URL | 描述 |
/index/_search | 搜索指定索引下的数据 |
/_aliases | 获取或操作索引的别名 |
/index/ | 查看指定索引的详细信息 |
/index/type/ | 创建或操作类型 |
/index/_mapping | 创建或操作mapping |
/index/_setting | 创建或操作设置(number_of_shards是补课更改的) |
/index/_open | 打开指定被关闭的索引 |
/index/_close | 关闭指定索引 |
/index/_refresh | 刷新索引(使新加内容对搜索可见,不保证数据被写入磁盘) |
/index/flush | 刷新索引(会触发Lucene提交) |
ElasticSearch Rest操作:
有两种方式:一种方式是通过REST请求URI,发送搜索参数;另外一种是通过REST请求体,发送搜索参数,而请求体允许你包含更容易表达和可阅读的JSON格式。
通过REST请求URI:
curl 'http://hadoop01:9200/test/_search?q=*&pretty'
#q=*:参数告诉elasticsearch,在test索引中匹配所有的文档
#pretty:参数告诉elasticsearch,返回形式打印JSON结果
通过REST请求体
上述匹配所有数据可以改成如下写法:
curl -H "Content-Type: application/json" -XPOST 'hadoop01:9200/test/_search?pretty' -d '{
"query":{
"match_all": {}
}
}'
与第一种方式不同的是在URI中替代传递q=*,使用POST提交,请求体包含JSON格式搜索。
查询语言介绍:
-
elasticsearch提供JSON格式领域特定语言执行查询。可参考QUERY_DSL
{
"query": {"match_all": {} }
}
query:定义查询
match_all:运行简单类型查询指定搜索中的所有文档。
除了指定查询参数,还可以指定其他参数来影响最终结果。
- match_all:只返回第一个文档
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match_all": {}},
"size": 1
}'
如果不指定size,默认是返回10条文档信息
- match_all: 返回11到20个文档信息(分页)
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match_all": {}},
"from": 10,
"size": 10
}'
from:指定文档索引从哪里开始,默认从0开始
size:从from开始,返回多个文档
这基本上为分页奠定了基础。
- match_all:根据account的balance降序排序返回10个文档(默认10个)
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match_all": {} },
"sort": {"balance": {"order": "desc"}}
}'
执行搜索:
默认的,我们搜索返回完整的JSON文档。而source(_source字段搜索点击量)。如果我们不想返回完整的JSON文档,可以使用source返回指定字段。
- 返回account_number and balance:
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match_all": {} },
"_source": ["balance","account_number"]
}'
- match查询,可以作为基本字段搜索查询
- 返回account_numbe=20:
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match": {"account_number": 20} }
}'
- 返回address=mill:
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match": {"address": "mill"} }
}'
- 返回address=mill or address=lane:
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match": {"address": "mill lane"} }
}'
- 返回短语匹配 address=mill lane
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {"match_phrase": {"address": "mill lane"} }
}'
布尔值(bool)查询:
- must:要求所有条件都要满足(类似于&&)
- 返回匹配:address=mill&address=lane
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {
"bool":{
"must": [
{"match": {"address": "mill"}},
{"match": {"address": "lane"}}
]
}
}
}'
- should:任何一个满足就可以(类似于||)
- 返回匹配address=mill or address=lane
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {
"bool":{
"should": [
{"match": {"address": "mill"}},
{"match": {"address": "lane"}}
]
}
}
}'
must_not:所有条件都不能满足(类似于!)
返回age=40 & state != ID
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {
"bool":{
"must": [
{"match": {"age": 40}}
],
"must_not":[
{"match": {"state": "ID"}}
]
}
}
}'
并行过滤器:
文档中score(_score字段是搜索结果)。score是一个数字型的,是一种相对方法匹配查询文档结果。分数越高,搜索关键字与该文档相关性越高;越低,搜索关键字与该文档相关性越低。
在elasticsearch中所有的搜索都会触发相关性分数计算。如果我们不使用相关性分数计算,那要使用另一种查询能力,构建过滤器。
过滤器是类似查询的概念,除了得以优化,更快的执行速度的两个主要原因:
1.过滤器不计算得分,所以比执行查询的速度快
2.过滤器可缓存在内存中,允许重复搜索
为了便于理解过滤器,先介绍过滤器搜索(like match_all, match, bool, etc.),可以与其他的普通查询搜索组合成一个过滤器。range filter,允许通过一个范围来过滤文档,一般用于数字或日期过滤使用过滤器搜索返回balances[20000, 30000]。换句话说,balance>= 20000 && balance<= 30000。
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/_search?pretty' -d '{
"query": {
"bool": {
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
},
"must": {
"match": {
"address": "lane"
}
}
}
},
"_source": [
"firstname",
"age",
"blance",
"account_number",
"address"
]
}'
过滤查询包含match_all查询(查询部分)和一系列过滤(过滤部分)。可以代替任何其他查询到查询部分以及其他过滤器部分。在上述情况下,过滤器范围只能
???
一般情况,最明智的方式决定是否使用filter or query,就看是否关心相关性分数。如果相关性不重要,那就使用filter,否则就使用query。
queries and filters 很类似关系型数据库中的 "SELECT WHERE CLAUSE"
执行聚合:
???
Settings 和 Mappings:
Settings:
维护索引库默认配置,当然经常用来修改默认配置。
例如:分片数量,父辈数量
查看:
curl -XGET 'http://hadoop01:9200/test/_settings?pretty'
操作不存在的索引:
curl -H "Content-Type: application/json" -XPUT 'http://hadoop01:9200/test1/' -d '{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}'
操作已存在的索引:
curl -H "Content-Type: application/json" -XPUT 'http://hadoop01:9200/test1/_settings' -d '{
"index": {
"number_of_replicas": 1
}
}'
一般只能在创建索引库的时候设置分配数量。如创建了5个分配,hash%5 -->分配, --->将分配改为6,数据的一致性就发生变化,就会产生hash一致性问题。
Mappings:
就是对索引库中索引的字段名称及其数据类型进行定义,类似于关系数据库中表建立时要定义字段名及其数据类型那样,(和solr中的schme类似)不过,ES的mapping比数据库灵活很多,它可以动态添加字段。一般不需要要指定mapping都可以,因为ES会自动根据数据格式定义它的类型,如果需要对某些字段添加特殊属性(如:定义使用其它分词器、是否分词、是否存储导等),就必须手动添加mapping
查询索引库的mapping信息:
curl -XGET 'http://hadoop01:9200/test/accout/_mapping?pretty'
mappings修改字段相关属性,例如:字段类型,使用哪种分词工具
下面是使用indexAnalyzer定义分词器,也可以使用index_analyzer定义分词器
操作不存在的索引:
curl -H "Content-Type: application/json" -XPUT 'http://hadoop01:9200/bigdata' -d '{
"mappings": {
"emp": {
"properties": {
"content": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}'
操作已存在的索引:
???
curl -H "Content-Type: application/json" -XPOST 'http://hadoop01:9200/test/accout' -d '{
"mappings": {
"properties": {
"address": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}'
通过操作,索引库的类型个数无法修改。
ElasticSearch优化:
-
关于创建:
调大系统的"最大打开文件数",建议32K甚至是64K
ulimit -a (查看)
ulimit -n 32000 (设置)
修改配置文件调整ES的JVM内存大小
1.修改bin/elasticsearch.in.sh中ES_MIN_MEM和ES_MAX_MEM的大小,建议设置一样大,避免频繁的分配内存,根据服务器内存大小,一般分配60%左右(默认256M)
2.如果使用searchwrapper插件启动ES的话则修改bin/service/elastic.conf(默认1024M,2.x以后不用考虑)
设置mlockall来锁定进程的物理内存地址
避免交换(swapped)来提高性能
修改文件conf/elasticsearch.yml:bootstrap.mlockall: true
分片多的话,可以提升建立索引的能力,5-20个比较合适。
如果分片数过少或过多,都会导致检索比较慢。分片数过多会导致检索时打开比较多的文件,另外也会导致多台服务器之间通讯。而分片数过少会导致单个分片索引过大,所以检索速度慢。建议单个分片最多存储20G左右的索引数据,所以,分片数量=数据总量/20G副本多的话,可以提升搜索的能力,但是如果设置很多副本的话也会对服务器造成额外的压力,因为需要同步数据。所以建议设置2~3个即可。
要定时对索引进行优化,不然segment越多,查询的性能就越差
索引量不是很大的情况下,可以将segment设置为1
???
curl -XPOST 'http://hadoop01:9200/test2/_optimize?max_num_segments=1'
java代码:
client.admin().indices().prepareOptimize("bigdata").setMaxNumSegments(1).get();
-
关于删除:
删除文档:在Lucene中删除文档,数据不会马上在硬盘上除去,而是在lucene索引中产生一个.del的文件,而在检索过程中这部分也会参与检索,lucene在检索过程会判断是否删除了,如果删除了再过滤掉。这样也会降低检索效率。所以可以执行清除文档。
???
curl -XPOST 'http://hadoop01:9200/test/_optimize?only_expunge_deletes=true'
java代码:
client.admin().indices().prepareOptimize("bigdata").setOnlyExpungeDeletes(true).get();
如果在项目开始的时候需要批量入库大量数据的话,建议将副本数设置为0。因为ES在索引数据的时候,如果有副本存在,数据也会马上同步到副本中,这样会对ES增加压力。待索引完成后将副本按需要改回来。这样可以提高索引效率。
关于配置:
去掉mapping中_all域,Index中默认会有_all域,(相当于solr配置文件中的拷贝字段text),这个会给查询带来方便,但是会增加索引时间和索引尺寸
"_all": {"enabled": "false'}
log输出的水平默认为trace,即查询超过500ms即为慢查询,就要打印日志,造成cpu和mem,io负载很高。把log输出水平改为info,可以减轻副武器的压力。
修改ES_HOME/conf/logging.yaml文件
或者修改ES_HOME/conf/elasticsearch.yaml