根据网上资料自己稍微整理了一下关于Elastcisearch的基本语法
参考链接:
https://blog.csdn.net/afeiqiang/article/details/83021144
https://www.itsvse.com/forum.php?mod=viewthread&tid=6334&extra=&ordertype=1
https://www.cnblogs.com/cxygg/p/9471372.html
https://blog.csdn.net/u011499747/article/details/78877922
https://www.cnblogs.com/heshun/articles/10658745.html
在Elasticsearch中,包含多个索引(Index),相应的每个索引可以包含多个类型(Type),这些不同的类型每个都可以存储多个文档(Document),每个文档又有多个属性。一个索引索引 (index) 类似于传统关系数据库中的一个数据库,是一个存储关系型文档的地方。 索引 (index) 的复数词为 indices 或 indexes 。
PUT /megacorp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
这个URI后面的1代表的是这条数据的ID,也可以字符串。如果不想自己指定ID,可以不传,但是必须使用POST来新增,这样的话Elasticsearch会给这条数据生成一个随机的字符串。
如果想对这条数据进行更新,可以重新请求这个URI,关键是这个ID要指定,然后修改json内容,这样就可以更新这条数据了。
根据ID检索到具体某条数据:
GET /megacorp/employee/1
结果:
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [
"sports",
"music"
]
}
}
其中_source就是我们存储的json信息,其他字段都很明了。
将HTTP动词由PUT改为GET可以用来检索文档,同样的,可以使用DELETE命令来删除文档,以及使用HEAD指令来检查文档是否存在。如果想更新已存在的文档,只需再次PUT。由此可见,Elasticsearch的作者深谙restful。
GET /megacorp/employee/_search
_search为es的关键字,意为全文搜索,搜索指定Index下的Type的全部文档,默认每页只显示10条,可以通过size字段改变这个设置,还可以通过from字段,指定位移(默认是从位置0开始)。返回结果的 took字段表示该操作的耗时(单位为毫秒),timed_out字段表示是否超时,hits字段表示命中的记录。
搜索last_name=Smith的数据:
GET /megacorp/employee/_search?q=last_name:Smith
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
这段查询和上面的例子是一样的,不过参数从简单的参数变成了一个复杂的json,不过复杂带来的优势就是控制力更强,我们可以对查询做出更多精细的控制。
根据last_name搜索,并且只关心年龄大于30的:
GET /megacorp/employee/_search
{
"query" : {
"bool": {
"must": {
"match" : {
"last_name" : "smith"
}
},
"filter": {
"range" : {
"age" : { "gt" : 30 }
}
}
}
}
}
这里涉及到几个es关键字,一一说明
bool:组合查询,要配合must、should、must_not、filter:关键字使用。
must:必须匹配的条件字段
should:should下面会带一个以上的条件,至少满足一个条件,这个文档就符合should
must_not:必须符不合的
filter:过滤器
以下查询将会找到 title 字段中包含 “how to make millions”,并且 “tag” 字段没有被标为 spam。 如果有标识为 “starred” 或者发布日期为2014年之前,那么这些匹配的文档将比同类网站等级高:
{
"bool": {
"must": { "match": { "title": "how to make millions" }},
"must_not": { "match": { "tag": "spam" }},
"should": [
{ "match": { "tag": "starred" }},
{ "range": { "date": { "gte": "2014-01-01" }}}
]
}
}
range是查找指定字段包含指定范围内的值(日期,数字或字符串)的文档,gt 表示_大于(_great than)
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"about" : "rock climbing"
}
}
}
上面这个搜索会返回about中包含rock或者climbing的数据,也就是关键词之间默认是or的关系。如果希望精确匹配这个短语呢?
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
就是用match_phrase查询。
先存入数据
PUT /_search
{
"title":"中信泰富的并购融资";
"summary":"它利用非金融性资产能源源不断地在证券市场上融资,采取发行新股和引入风险投资相结合收购恒昌企业,结果各方均取得了满意的结果。"
}
对title与summary符和查询key的字符进行高亮,默认是用来包裹。
GET /_search
{
"query" : {
"multi_match": { "query": "投资" }
},
"highlight" : {
"fields" : {
"title": {},
"summary" : {}
}
}
}
返回的结果里面每个 hit 多了一个类似这样部分:
"highlight" : {
"summary" : [
"它利用非金融性资产能源源不断地在证券市场上融资,采取发行新股和引入风险投资相结合收购恒昌企业,结果各方均取得了满意的结果。",
"其融资的方式主要有发行新股、可换股债券、引入风险投资等。而这些巨额的融资行动是和投资银行紧密充分的合作分不开的。从中得出一些对我国上市公司并购融资有益的启示,可作为并购融资实践的参考。"
],
"title" : [
"中信泰富的并购融资"
]
}
在聚合之前,需要做些修改,因为Elasticsearch默认是不支持对text类型的数据聚合的,所以需要先开启:
PUT zhifou/doc/1
{
"name":"顾老二",
"age":30,
"from": "gu",
"desc": "皮肤黑、武器长、性格直",
"tags": ["黑", "长", "直"]
}
PUT zhifou/doc/2
{
"name":"大娘子",
"age":18,
"from":"sheng",
"desc":"肤白貌美,娇憨可爱",
"tags":["白", "富","美"]
}
PUT zhifou/doc/3
{
"name":"龙套偏房",
"age":22,
"from":"gu",
"desc":"mmp,没怎么看,不知道怎么形容",
"tags":["造数据", "真","难"]
}
PUT zhifou/doc/4
{
"name":"石头",
"age":29,
"from":"gu",
"desc":"粗中有细,狐假虎威",
"tags":["粗", "大","猛"]
}
PUT zhifou/doc/5
{
"name":"魏行首",
"age":25,
"from":"广云台",
"desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!",
"tags":["闭月","羞花"]
}
现在的需求是查询from是gu的人的平均年龄。
GET zhifou/doc/_search
{
"query": {
"match": {
"from": "gu"
}
},
"aggs": {//表示聚合函数开始
"my_avg": {//起的别名
"avg": {//聚合函数类型
"field": "age"//key与value
}
}
},
"_source": ["name", "age"]//_source表示只显示指定字段
}
查询结果如下
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {//hits表示命中多少记录
"total" : 3,
"max_score" : 0.6931472,
"hits" : [
{
"_index" : "zhifou",
"_type" : "doc",
"_id" : "4",
"_score" : 0.6931472,
"_source" : {
"name" : "石头",
"age" : 29
}
},
{
"_index" : "zhifou",
"_type" : "doc",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"name" : "顾老二",
"age" : 30
}
},
{
"_index" : "zhifou",
"_type" : "doc",
"_id" : "3",
"_score" : 0.2876821,
"_source" : {
"name" : "龙套偏房",
"age" : 22
}
}
]
},
"aggregations" : {
"my_avg" : {
"value" : 27.0
}
}
}
虽然我们已经使用_source对字段做了过滤,但是还不够。我不想看都有哪些数据,只想看平均值怎么办?别忘了size!
GET zhifou/doc/_search
{
"query": {
"match": {
"from": "gu"
}
},
"aggs": {
"my_avg": {
"avg": {
"field": "age"
}
}
},
"size": 0,
"_source": ["name", "age"]
}
查询结果如下
{
"took" : 8,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"my_avg" : {
"value" : 27.0
}
}
}
查询结果中,我们看hits下的total值是3,说明有三条符合结果的数据。最后面返回平均值是27。
将上例中的avg替换成为max
GET zhifou/doc/_search
{
"query": {
"match": {
"from": "gu"
}
},
"aggs": {
"my_max": {
"max": {
"field": "age"
}
}
},
"size": 0
}
查询结果如下
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"my_max" : {
"value" : 30.0
}
}
}
用法同上,不在缀述
按年龄分组
插入数据
PUT zhifou/doc/1
{
"name":"顾老二",
"age":25,
"from": "gu",
"desc": "皮肤黑、武器长、性格直",
"tags": ["黑", "长", "直"]
}
PUT zhifou/doc/2
{
"name":"大娘子",
"age":18,
"from":"sheng",
"desc":"肤白貌美,娇憨可爱",
"tags":["白", "富","美"]
}
PUT zhifou/doc/3
{
"name":"龙套偏房",
"age":22,
"from":"gu",
"desc":"mmp,没怎么看,不知道怎么形容",
"tags":["造数据", "真","难"]
}
PUT zhifou/doc/4
{
"name":"石头",
"age":29,
"from":"gu",
"desc":"粗中有细,狐假虎威",
"tags":["粗", "大","猛"]
}
PUT zhifou/doc/5
{
"name":"魏行首",
"age":25,
"from":"广云台",
"desc":"仿佛兮若轻云之蔽月,飘飘兮若流风之回雪,mmp,最后竟然没有嫁给顾老二!",
"tags":["闭月","羞花"]
}
GET user/student/_search
{
"query": {
"match_all": {}
},
"aggs": {
"fz": {
"terms": {
"field": "age"
}
}
}
}
查询结果
{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 1,
"hits": [
{…………},//这里省略命中结果
"aggregations": {
"fz": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 25,
"doc_count": 2//年龄为25的有两个记录
},
{
"key": 18,
"doc_count": 1
},
{
"key": 22,
"doc_count": 1
},
{
"key": 29,
"doc_count": 1
}
]
}
}
}
现在我想要查询所有人的年龄段,并且按照1520,2025,25~30分组,并且算出每组的平均年龄。
分析需求,首先我们应该先把分组做出来。
GET zhifou/doc/_search
{
"size": 0, //表示显示0条命中记录,因为我们的目标是分组结果,所以命中记录不是我们关心的,只要数量对就行了,不需要在把记录显示出来
"query": {
"match_all": {}
},
"aggs": {
"age_group": {//别名
"range": {
"field": "age",//分组字段
"ranges": [//范围
{
"from": 15,
"to": 20
},
{
"from": 20,
"to": 25
},
{
"from": 25,
"to": 30
}
]
}
}
}
}
查询结果如下
{
"took": 5,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 0,
"hits": []
},
"aggregations": {
"age_group": {
"buckets": [
{
"key": "15.0-20.0",
"from": 15,
"to": 20,
"doc_count": 1
},
{
"key": "20.0-25.0",
"from": 20,
"to": 25,
"doc_count": 1
},
{
"key": "25.0-30.0",
"from": 25,
"to": 30,
"doc_count": 3
}
]
}
}
}
那么接下来,我们就要对每个小组内的数据做平均年龄处理。
GET zhifou/doc/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"age_group": {
"range": {
"field": "age",
"ranges": [
{
"from": 15,
"to": 20
},
{
"from": 20,
"to": 25
},
{
"from": 25,
"to": 30
}
]
},
"aggs": {
"my_avg": {
"avg": {
"field": "age"
}
}
}
}
}
}
查询结果如下
{
"took": 28,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 5,
"max_score": 0,
"hits": []
},
"aggregations": {
"age_group": {
"buckets": [
{
"key": "15.0-20.0",
"from": 15,
"to": 20,
"doc_count": 1,
"my_avg": {
"value": 18
}
},
{
"key": "20.0-25.0",
"from": 20,
"to": 25,
"doc_count": 1,
"my_avg": {
"value": 22
}
},
{
"key": "25.0-30.0",
"from": 25,
"to": 30,
"doc_count": 3,
"my_avg": {
"value": 26.333333333333332
}
}
]
}
}
}
注意:聚合函数的使用,一定是先查出结果,然后对结果使用聚合函数做处理
GET /_count
{
"query": {
"match_all": {}// "last_name" : "Smith"对指定字段计数
}
}
查询结果如下
{
"count": 12,
"_shards": {
"total": 20,
"successful": 20,
"skipped": 0,
"failed": 0
}
}
GET _cluster/health
GET _nodes/stats
GET my_index/_stats
GET my_index,another_index/_stats
GET _all/_stats
GET _cluster/pending_tasks