Elasticsearch常用基本语法

根据网上资料自己稍微整理了一下关于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:组合查询,要配合mustshouldmust_notfilter:关键字使用。
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":"中信泰富的并购融<em>资</em>";
    "summary":"它利用非金融性资产能源源不断地在证券市场上融资,采取发行新股和引入风险投资相结合收购恒昌企业,结果各方均取得了满意的结果。"
}

对title与summary符和查询key的字符进行高亮,默认是用来包裹。

GET /_search
{
    
    
    "query" : {
    
    
        "multi_match": {
    
     "query": "投资" }
    },
    "highlight" : {
    
    
        "fields" : {
    
    
            "title": {
    
    },
            "summary" : {
    
    }
        }
    }
}

返回的结果里面每个 hit 多了一个类似这样部分:

"highlight" : {
    
    
          "summary" : [
            "它利用非金融性<em>资</em>产能源源不断地在证券市场上融<em>资</em>,采取发行新股和引入风险<em>投</em><em>资</em>相结合收购恒昌企业,结果各方均取得了满意的结果。",
            "其融<em>资</em>的方式主要有发行新股、可换股债券、引入风险<em>投</em><em>资</em>等。而这些巨额的融<em>资</em>行动是和<em>投</em><em>资</em>银行紧密充分的合作分不开的。从中得出一些对我国上市公司并购融<em>资</em>有益的启示,可作为并购融<em>资</em>实践的参考。"
          ],
          "title" : [
            "中信泰富的并购融<em>资</em>"
          ]
        }

简单聚合

在聚合之前,需要做些修改,因为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":["闭月","羞花"]
}

avg

现在的需求是查询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。

max

将上例中的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
    }
  }
}

min、sum

用法同上,不在缀述

分组查询

简单分组

按年龄分组
插入数据

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

猜你喜欢

转载自blog.csdn.net/qq_15098623/article/details/103413188