我是啤酒就辣条。但行好事,莫问前程。
官网为咱们提供了多种语言操作Elasticsearch的API,能够很不便的在我的项目中操作。学习利用原生申请操作Elasticsearch,不便保护数据库,还能放慢学习应用不同语言的API。
本博客应用kibana发动申请,应用kibana能够查看快捷键。
索引操作
创立索引
创立索引应用PUT
申请,前面跟上索引名称就好了,因为7.x默认type为_doc
,所以前面不用跟上type了。在PUT简略申请同时,能够加上JSON申请体,进行简单创立。
PUT /user{ "settings": { "index": { "number_of_shards": 3, "number_of_replicas": 2 } }, "mappings": { "properties": { "name": { "type": "text" }, "age": {"type": "short"}, "city":{"type": "keyword"} } }}
创立索引user
,能够通过参数setting
设置分片和正本数,通过number_of_shards
设置一共有3个分片,通过number_of_replicas
给每个分片设置2个正本,默认不指定的话,这两个参数都是1。通过mappings
规定文档各个Filed插入类型。此外,还能够设置aliases
字段,给索引创立别名,这样不仅能够通过别名拜访该索引,还能够定义查问条件、指定查问分片等等,详情请参考。
删除索引
删除索引,应用DELETE申请。
DELETE /user
查看索引
查看索引,应用GET
申请,能够查看索引设置的参数。
删除之后,我又从新增加索引,没有设置settings,所以分片和正本都是1。
你也能够通过在索引前面加参数来查看某一具体参数,如:
GET /user/_settingsGET /user/_mappingsGET /user/_aliases
批改索引局部设置
能够通过PUT
申请批改局部索引的settings,例如,分片正本数量能够批改,然而分片数量不能够通过这种形式批改。
PUT /user/_settings{ "number_of_replicas": 3 }
能够通过以上申请,批改分片正本。
文档操作
创立好索引,来看下文档的增删改查,这是日常业务用的最多的中央。
插入文档
新增文档应用PUT
、POST
申请。
PUT /<target>/_doc/<_id>POST /<target>/_doc/PUT /<target>/_create/<_id>POST /<target>/_create/<_id>
target
为索引名称,_doc
为默认type。通过前两种申请可看出,id能够自行指定,也能够由ES主动生成。_create
能够保障只有当文档不存在的时候进行插入,而_doc
还能够用于文档更新。
POST /user/_doc/1{ "name":"pjjlt", "age":26, "city":"sjz"}
更新文档
更新文档能够应用PUT
或者POST
申请关键字,全量更新。
POST /user/_doc/1{ "name":"pjjlt", "age":3, "city":"sjz"}
还能够通过_update
命令部分更新,所谓部分更新,是讲申请体内不须要退出全副字段,只退出须要批改的字段就好,其余字段不变。全量更新会替换整个文档。
POST /user/_update/1{ "doc":{ "age": 26 }}
此外还能够通过脚本批改,例如将所有存在age
字段的文档,其值改成5岁。
POST /user/_update_by_query{ "script": { "source": "ctx._source['age']=5" }, "query": { "bool": { "must": [ { "exists": { "field": "age" } } ] } }}
此外update
和_update_by_query
字段还能够批改Filed
,例如将name批改成name1,这块内容应用较少,如感兴趣,请参考官网文档。
删除文档
删除文档能够应用DELEETE
申请,删除指定id的文档,也能够应用_delete_by_query
,删除指定条件下的文档。
DELETE /user/_doc/1
POST /user/_delete_by_query{ "query": { "match": { "name": "pjjlt" } }}
查找文档
查找文档是ES操作最精彩的局部,这里只介绍简略的查问,简单查问、聚合查问前面会介绍。
依据id查问某文档。
GET /user/_doc/1
查找某索引下的全副文档
GET /user/_search?pretty
pretty
参数在浏览器中才会发挥作用,格式化返回json的。以上这条命令默认返回10条数据,想返回更多数据能够增加size
字段。
GET /user/_search?pretty&size=20
能够看出,数据局部在hits
外面,Spring提供的elasticsearch客户端会有对应的实体类,在我的项目中很不便的应用。上面看下这几局部的含意。
元素 | 含意 |
---|---|
took | 运行查问须要多长时间 |
time_out | 申请是否超时 |
_shards | 搜寻了多少分片,多少胜利 多少跳过,多少失败 |
hits.total | 总共有多少数据 |
hits._max_score | 查问到的文档中,关联度最大文档分数 |
hits.hits._source | 查问到的数据 |
hits.hits.id | 某文档的主键 |
批量操作
批量操作是指,一批命令同时执行(缩小IO),这些命令不肯定是同种类型。
应用_bulk
命令能够进行文档的批量增删改。
POST _bulk{ "update" : { "_index" : "user", "_id" : "1" } }{ "doc" : {"age" : 18} }{ "create" : { "_index" : "user", "_id" : "2" } }{ "name" : "小明","age":32,"city":"beijing" }{ "create" : { "_index" : "user", "_id" : "3" } }{ "name" : "小红","age":21,"city":"sjz" }{ "create" : { "_index" : "user", "_id" : "4" } }{ "name" : "mark","age":22,"city":"tianjin" }{ "delete" : { "_index" : "user", "_id" : "4" } }
以上命令更新了id为1文档的年龄,新增id为2、3、4的文档,再删除id为4的文档。
上边的命令堆在一起不不便看,上面独自写看,不便读者查看。
批量新增
POST _bulk{ "create" : { "_index" : "user", "_id" : "2" } }{ "name" : "小明","age":32,"city":"beijing" }{ "create" : { "_index" : "user", "_id" : "3" } }{ "name" : "小红","age":21,"city":"sjz" }{ "index" : { "_index" : "user", "_id" : "4" } }{ "name" : "mark","age":22,"city":"tianjin" }
create
命令是只有文档不存在,才会插入,index
会判断如果存在就更新,不存在就插入。
批量更新
POST _bulk{ "update" : { "_index" : "user", "_id" : "1" } }{ "doc" : {"age" : 18} }{ "update" : { "_index" : "user", "_id" : "2" } }{ "doc" : {"age" : 20} }
和新增一样,update
命令下一行须要紧跟这data数据。
批量删除
POST _bulk{ "delete" : { "_index" : "user", "_id" : "3" } }{ "delete" : { "_index" : "user", "_id" : "4" } }
批量查找
批量查找,应用_mget
关键字,批量查找如果不逾越索引,也具备简写模式。
GET /_mget{ "docs": [ { "_index": "user", "_id": "1" }, { "_index": "user", "_id": "2" } ]}# 还能够简写模式POST /user/_mget{ "ids": [ "1", "2", "3" ]}
DSL查问
Elasticsearch提供了一个残缺的基于JSON的查问DSL(畛域特定语言)来定义查问。能够将查问DSL看作查问的AST(形象语法树),它由两种类型的子句组成:Leaf query clauses(叶查问子句)和Compound query clauses(复合查问子句)
以上摘自官网,简略来说,DSL就是将查问条件放到JSON中,进行查问。
Leaf query clauses在特定字段上查找特定的值,例如match
、term
、range
查问等等。
Compound query clauses将叶查问子句和其余合乎查问子句联合起来,例如bool
查问等等。
match
match是一个规范查问,当查问一个文本的时候,会先将文本分词。当查问确切值的时候,会搜寻给定的值,例如数字、日期、布尔或者被not_analyzed的字符串。
GET /user/_search{ "query": { "match": { "name":"小明" } }}
下面的操作会先将“小明”分词为“小”、“明”(当然具体还要看你的分词器),而后再去所有文档中查找与之相匹配的文档,并依据关联度排序返回。
match_phrase
match_phrase会保留空格,match会把空格疏忽。
GET /user/_search{ "query": { "match_phrase": { "name":"小 明" } }}
留神,分词是空格会给前一个元素,比方下面的字符串分子之后是,“小 ”,“明”。
multi_match
多字段查问,一个查问条件,看所有多个字段是否有与之匹配的字段。前面咱们也能够应用should
更加灵便。
GET /user/_search{ "query": { "multi_match": { "query": "哈哈", "fields": [ "name","city" ] } }}
match_all
匹配所有,并可设置这些文档的_score
,默认_score
为1,辣条君认为这里没有计算_score
,所以速度会快很多。
GET /user/_search{ "query": { "match_all": { "boost" : 1.2 } }}
boost
参数能够省略,默认是1。
term
term是一种齐全匹配,次要用于准确查找,例如数字、ID、邮件地址等。
GET /user/_search{ "query": { "term": { "age": 18 } }}
terms
terms是term多条件查问,参数能够传递多个,以数组的模式示意。
GET /user/_search{ "query": { "terms": { "age":[18,21] } }}
wildcard
通配符,看示例容易了解,通配符能够解决分词匹配不到的问题,例如'haha' 能够通过'*a'匹配。
GET /user/_search{ "query": { "wildcard": { "name":"*a" } }}
exists
查看某文档是否有某属性,返回蕴含这个Filed
的文档。
GET /user/_search{ "query": { "exists": { "field": "name" } }}
fuzzy
返回与查问条件雷同或者类似的匹配内容。
GET /user/_search{ "query": { "fuzzy": { "name":"mjjlt" } }}
搜寻条件是mjjlt
,能够搜进去name为pjjlt
的文档。这个操作是不是在百度的时候常常见到呢?
ids
多id查问,这个id是主键id,即你规定或者主动生成那个。
GET /user/_search{ "query": { "ids": { "values":[1,2,3] } }}
prefix
前缀匹配
GET /user/_search{ "query": { "prefix": { "name":"pj" } }}
range
范畴匹配。参数能够是 gt(大于)、gte(大于等于)、lt(小于)、lte(小于等于)
GET /user/_search{ "query": { "range": { "age":{ "gt":1, "lt":30 } } }}
regexp
正则匹配。value是正则表达式,flags是匹配格局,默认是ALL,开启所有。更多格局请戳
GET /user/_search{ "query": { "regexp": { "name":{ "value": "p.*t", "flags": "ALL" } } }}
bool
bool 能够用来组合其余子查问。其中常蕴含的子查问蕴含:must、filter、should、must_not
must
must
外部的条件必须蕴含,外部条件是and
的关系。如查看所有name中蕴含“小”并且age是32的用户文档。
GET /user/_search{ "query": { "bool" : { "must": [ {"term" : { "name" : "小" }}, {"term" : { "age" : 32 }} ] } }}
filter
filter
是文档通过一些条件过滤下,这是四个关键词中惟一和关联度无关的,不会计算_score,常常应用的过滤器会产生缓存。
GET /user/_search{ "query": { "bool" : { "filter": { "term" : { "name" : "小" } } } }}
比照两张图能够看出,filter并没有计算_score,搜寻速度较快。
must_not
这个和must
相同,文档某字段中肯定不能蕴含某个值,相当于“非”。
should
should
能够看做or
的关系,例如上面查问name蕴含"小"或者年龄是18岁的用户。
GET /user/_search{ "query": { "bool" : { "should": [ {"term" : { "name" : "小" }}, {"term" : { "age" : 18 }} ] } }}
聚合查问
Elasticsearch除全文检索性能外提供的针对Elasticsearch数据做统计分析的性能。能够查问某组数据的最大最小值,分组查问某些数据。
- Metric(指标): 指标剖析类型,如计算最大值、最小值、平均值等等 (对桶内的文档进行聚合剖析的操作)
- Bucket(桶): 分桶类型,相似SQL中的GROUP BY语法 (满足特定条件的文档的汇合)
- Pipeline(管道): 管道剖析类型,基于上一级的聚合剖析后果进行在剖析
Metric(指标)数据
罕用数学操作
这里罕用的数学操作有min
(最小)、max
(最大)、sum
(和)、avg
(平均数)。留神这些操作只能输入一个剖析后果。应用形式大同小异。
GET /user/_search{ "aggs" : { "avg_user_age" : { "avg" : { "field" : "age" } } }}
以上示例查问所有用户的平均年龄,返回所有文档和聚合查问后果。aggs
是聚合查问关键词,avg_user_age
是查问名称,用户能够自行定义。
cardinality
计算某字段去重后的数量
GET /user/_search{ "aggs" : { "avg_user" : { "cardinality" : { "field" : "age" } } }}
能够计算,所有文档中年龄不雷同的文档个数。
percentiles
对指定字段的值按从小到大累计每个值对应的文档数的占比,返回指定占比比例对应的值。默认统计百分比为[ 1, 5, 25, 50, 75, 95, 99 ]
GET /user/_search{ "aggs" : { "avg_user" : { "percentiles": { "field" : "age" } } }}# 返回值(省略文档局部,只剖析后果局部) "aggregations" : { "avg_user" : { "values" : { "1.0" : 12.0, "5.0" : 12.0, "25.0" : 20.25, "50.0" : 29.0, "75.0" : 57.75, "95.0" : 123.0, "99.0" : 123.0 } } }
能够看出,前1%的用户小于12岁,5%的用户小于12岁,25%的用户小于20.25岁,50%的用户小于29岁。。。
percentile_ranks
percentiles是通过百分比求出文档某字段,percentile_ranks是给定文档中的某字段求百分比。
GET /user/_search{ "aggs" : { "avg_user" : { "percentile_ranks": { "field" : "age", "values" : [18, 30] } } }}# 返回值(省略文档局部,只剖析后果局部) "aggregations" : { "avg_user" : { "values" : { "18.0" : 18.51851851851852, "30.0" : 54.44444444444445 } } }
能够看出,小于等于18岁的用户有18.52%,小于等于30岁的用户有54.4%。
top_hits
top_hits能够失去某条件下top n的文档。
GET /user/_search{ "aggs": { "avg_user" : { "top_hits": { "sort": [ { "age": { "order": "asc" } } ], "size": 1 } } }, "size": 0}
取年龄最小的那一个。
Bucket(桶)
相似于分组的概念。
terms
依据给定的filed分组,返回每组多少文档。
GET /user/_search{ "aggs" : { "avg_user" : { "terms": { "field": "city" } } }}
以上依据城市分组,看每个城市有多少用户。
ranges
依据区间分组
GET /user/_search{ "aggs": { "price_ranges": { "range": { "field": "age", "ranges": [ { "to": 20 }, { "from": 20, "to": 30 }, { "from": 30 } ] } } }}
能够查看每个年龄层的用户数量。
还有些很乏味的指令,例如[IP range]能够依据ip段区间分组,当前用到再说吧,心愿文本能够不段更新的说...