注意事项:
一、settings
- number_of_shards:索引的分片数量一般千万级别的话单分片就可满足。ES作为分布式存储系统读会放大,分片越多放大倍数越高。
- refresh_interval 默认1s,对于高并发写系统,调大此值会提升写入性能。
- number_of_replicas:副本数,设置为0可以提升写入性能,副作用就是磁盘故障会存在丢数风险
- 满足业务情况下使用最小存储类型,能int不用long,能short不用int(5.x之后存在特例,keyword 和 number)。
二、枚举类型
5.X以上版本数字类型采用了BKD树结构, 对于状态、响应码等枚举类型,如果无范围查询,可设置成keyword提升查询效率
对于已存在的索引升级版本号性能下降也可将term查询更换为range查询,跳过最耗时的BitSet的构造过程 (filter情况下 range会进行cache)。
三、_id
日志等不需要修改的数据建议使用es自动生成id,不要使用UUID,有唯一id的比如mysql自增主键可以使用该自增id
四、filter
尽量使用filter,filter可以和query混用
Filter的结果能被filter cache
Filter的过程不参与lucene的打分
参考地址:参考地址
api文档地址
https://www.elastic.co/guide/cn/elasticsearch/guide/current/_ranges.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
ES的document核心元数据:_index,_type,_id,_source
分片数一单指定就无法修改,mapping一但确定只能新增属性不能修改
1.查看集群全部索引
curl -XGET "http://192.168.137.201:9200/_cat/indices"
返回结果
health index pri rep docs.count docs.deleted store.size pri.store.size
yellow test_index 5 1 1000 0 424.4kb 424.4kb
2.新建索引
es索引名不支持大写
curl -XPUT "http://192.168.137.201:9200/test_index" -H 'Content-Type: application/json' -d'
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 1
}
}'
新建索引时指定type和mapping,index控制是否可以作为搜索条件
curl -XPUT "http://localhost:9200/test_index" -H 'Content-Type: application/json' -d'
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 1
},
"mappings": {
"test_type":{
"dynamic": false,
"properties": {
"name":{
"type": "keyword",
"index": true
},
"age":{
"type": "long",
"index": true
}
}
}
}
}'
_ttl一般设置为false,表示禁用自动删数据(ES2.1版本),5.x以上版本字符类型请用keyword(普通查询,不需查询设置index:false属性),全文搜索使用text,dynamic一般设为false,表示会忽略掉mapping中不存在的字段,避免误修改mapping,_all一般设为false,表示不启用额外的_all字段。
关于 dynamic:
- 动态映射(dynamic:true):动态添加新的字段(或缺省)。
- 静态映射(dynamic:false):忽略新的字段。在原有的映射基础上,当有新的字段时,不会主动的添加新的映射关系,只作为查询结果出现在查询中。
- 严格模式(dynamic: strict):如果遇到新的字段,就抛出异常。
store:值为yes和no,默认为no。指定是否将该字段的原始文档写入索引。在elasticsearch中,因为_source中(_source下面解析)已经存储了一份原始文档,在索引中再存储原始文档就多余了,所以Elasticsearch默认是把store属性设置为no。
3.删除索引
curl -XDELETE "http://192.168.137.201:9200/test_index"
4.打开、关闭索引
关闭的索引不能crud
curl -XPOST "http://192.168.137.201:9200/test_index/_open"
curl -XPOST "http://192.168.137.201:9200/test_index/_close"
5 给上面的索引新建type和mapping
curl -XPOST "http://192.168.137.201:9200/test_index/test_type/_mapping" -H 'Content-Type: application/json' -d'
{
"_ttl": {
"enabled": false
},
"dynamic": false,
"_all": {
"enabled": false
},
"properties": {
"name":{
"type": "keyword",
"store": true,
"index": true
}
}
}'
store: 是否单独存储, 默认数据会存储到_source元数据,并由此返回,如果设置为true会将该字段单独存储一份,一般不需要单独存储,因为各种检索条件肯定会导致_source进行磁盘io。如果有大字段不需要返回的使用源过滤就可以,如果是无用大字段根本不需要存储或者应该放HBase。
index, 是否分析
-
如果是no,则无法通过检索查询到该字段;一般是true
-
如果设置为not_analyzed则会将整个字段存储为关键词,常用于汉字短语、邮箱等复杂的字符串;
-
如果设置为analyzed则将会通过默认的standard分析器进行分析
null_value: 字段为空, 可设置默认值 NA, 搜索时可以搜搜, 适合all
analyzer: 分词器, 默认 standard, 一般设置 ik。 适合。all
include_in_all: 默认es对每个文档设置一个, 让每个字段被搜索到, 如果不想搜索到,
就可以设置false,默认即可
format: 格式化
如:
"date": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
更多属性详细的说明请查看api:es权威指南api
6.设置索引别名为test
curl -XPUT "http://192.168.137.201:9200/test_index/_alias/test"
可以为多个索引设置相同的别名,查询时根据别名查询所有的index,更新删除必须使用真实index,
别名的好处一:用户无感知的索引重建,比如新建一个索引将之前的数据导入,然后切换别名,再将之前的索引删除。
POST /_aliases?pretty
{
"actions": [
{
"remove": {
"index": "visitor_logs_2018",
"alias": "visitor_logs"
}
},
{
"add": {
"index": "visitor_logs_2018_01",
"alias": "visitor_logs"
}
}
]
}
别名好处二:大数据量管理,比如删除历史数据,基于时间的多索引,直接切换别名,然后迁移完毕后删除历史数据比如一年前的迁到HBase,直接删除旧的索引,此时删除是物理删除不是逻辑删除,后期不用做合并
7 获取索引的mapping,settings,别名
curl -XGET "http://192.168.137.201:9200/test_index/_mappings"
curl -XGET "http://192.168.137.201:9200/test_index/_settings"
curl -XGET "http://192.168.137.201:9200/test_index/_aliases"
8 插入数据
curl -XPUT "http://192.168.137.201:9200/test_index/test_type/1" -H 'Content-Type: application/json' -d'
{
"name":"你是谁"
}'
type后面为文档id
我们分别插入三条数据,你是谁、马小云、马小腾
9 前缀查询
curl -XGET "http://192.168.137.201:9200/test_index/test_type/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"prefix": {
"name": "马"
}
}
}'
返回结果
{
"took": 67,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "test_index",
"_type": "test_type",
"_id": "2",
"_score": 1,
"_source": {
"name": "马小云"
}
},
{
"_index": "test_index",
"_type": "test_type",
"_id": "3",
"_score": 1,
"_source": {
"name": "马小腾"
}
}
]
}
}
10 精确查询term
term查询通常使用constant_score以非评分模式来执行,放到filter内跳过分数计算提高性能
curl -XPOST "http://192.168.137.201:9200/test_index/test_type/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"constant_score": {
"filter": {
"term": {
"name": "马小云"
}
},
"boost": 1
}
}
}'
11 bool查询
must
所有的语句都 必须(must) 匹配,与 AND 等价。
must_not
所有的语句都 不能(must not) 匹配,与 NOT 等价。
should
至少有一个语句要匹配,与 OR 等价。
curl -XGET "http://192.168.137.201:9200/test_index/test_type/_search" -H 'Content-Type: application/json' -d'
{
"query" : {
"constant_score": {
"filter": {
"bool" : {
"should" : [
{ "term" : {"name" : "马小云"}},
{ "term" : {"name" : "马小腾"}}
],
"must_not" : [
{
"term" : {"name" : "xx"}
}
],
"must":{ "term" : {"name" : "马小云"}}
}
}
}
}
}'
12 修改已上线的mapping新增字段,老的字段无法更改只能通过重建索引
POST /test_index/test_type/_mapping
{
"properties": {
"title": {
"type": "text"
},
"age": {
"type": "integer"
}
}
}
新增一条数据
PUT /test_index/test_type/4
{
"name": "你是谁",
"title":"who am i",
"age":3
}
再次查询
curl -XGET "http://192.168.137.201:9200/test_index/test_type/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must":{
"term":{"name":"你是谁"}
}
}
},
"boost": 1.2
}
}
}'
查询结果
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1.2,
"hits": [
{
"_index": "test_index",
"_type": "test_type",
"_id": "1",
"_score": 1.2,
"_source": {
"name": "你是谁"
}
},
{
"_index": "test_index",
"_type": "test_type",
"_id": "4",
"_score": 1.2,
"_source": {
"name": "你是谁",
"title": "who am i",
"age": 3
}
}
]
}
}
13 range
gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)
curl -XGET "http://192.168.137.201:9200/test_index/test_type/_search" -H 'Content-Type: application/json' -d'
{
"query" : {
"constant_score" : {
"filter" : {
"range" : {
"age" : {
"gte" : 3,
"lte" : 5
}
}
}
}
}
}'
用于日期
"range" : {
"timestamp" : {
"gt" : "now-1h"
}
}
"range" : {
"timestamp" : {
"gt" : "2014-01-01 00:00:00",
"lt" : "2014-01-01 00:00:00||+1M"
}
}
14: 分页
curl -XGET "http://192.168.137.201:9200/test_index/test_type/_search" -H 'Content-Type: application/json' -d'
{
"from":0,
"size":2,
"query" : {
"match_all": {}
}
}'