一个分布式、可扩展、实时的全文搜索与数据分析引擎。它能从项目一开始就赋予你的数据以搜索、分析和探索的能力。
它提供了全文搜索、结构化搜索、数据分析、复杂的语言处理、地理位置和对象间关联关系处理等功能,十分强大。
目前在数据聚合和日志搜集领域很热门。
数据存放的概念
ES对于数据的几种概念:索引
、类型
、文档
、搜索
及聚合
ES天生就是分布式、集群化的一套系统,
文档是ES中数据单位,例如一个user对象:
{
"name": "Li",
"email": "dalaoha@gmail.com",
"info": {
"age": 24,
"height": 77
},
"join_date": "2018/12/12"
}
就是一个文档
索引和类型为定位到一个文档所需的路径
ES和SQl类数据库的数据层级关系如下
DB ⇒ Databases ⇒ 表(Tables) ⇒ 行(Rows) ⇒ 列(Columns)
ES ⇒ 索引(Indices) ⇒ 类型(Types) ⇒ 文档(Documents) ⇒ 字段(Fields)
交互
ES默认提供两个端口 9200 和 9300,9200 提供了RESTful风格的API接口,9300使用TCP交互
我们可以将一般查询请求递交给集群内任何一个节点,都可以得到相同的结果。
官方提供了几个语言的客户端https://www.elastic.co/guide/en/elasticsearch/client/index.html
对于客户端的选择,9300端口的TCP客户端性能高于9200的RESTful端口,但是这个客户端很庞大,他会启动一个节点加入集群,甚至可以设置这个节点存放数据,作为节点参与到集群中。一般情况情况下,应该使用RESTful的客户端,官方在5.6版本时提供了High RESTful Client
,对以往的RESTful客户端进行了包装。
ES拥有一套自己的生态链,其中Kibana作为聚合面板被广泛使用。
我们可以使用Kibana
作为一个控制台来了解如何使用ES,虽说有点大材小用了。
RESTful API 基础样例
因为使用这种方式,构成请求的协议为HTTP,我们甚至可以使用curl这种工具来发起请求
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
被 < > 标记的部件:
Tables | Are |
---|---|
VERB | 适当的 HTTP 方法: GET 、 POST 、 PUT 、 HEAD 或者 DELETE
|
PROTOCOL | 默认http,如果有https代理则https |
HOST | ES集群中任意节点的主机名 |
PORT | 运行 ES HTTP 服务的端口号,默认 9200 。 |
PATH | API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。 |
QUERY_STRING | 任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读) |
BODY | 可选:一个 JSON 格式的请求体 |
API请求会返回HTTP状态码和一个结果json串
例如查询ES中文档的数量
curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
"query": {
"match_all": {}
}
}
上述url在Kibana和RESTful客户端中简写为
GET _count?pretty
其中pretty只是为了返回的json更容易辨认些
会返回这样的内容:
{
"count": 3,
"_shards": {
"total": 11,
"successful": 11,
"failed": 0
}
}
如果需要查看http状态码,就在curl中添加 -i 参数,打印请求头部。
基础文档操作
CRUD
"添加(insert)、修改(update)")添加(insert)、修改(update)
put /dev/emp/1
{
"name": "Li",
"email": "dalaoha@gmail.com",
"info": {
"age": 24,
"height": 77
},
"join_date": "2018/12/21"
}
{
"_index": "dev", // 索引
"_type": "emp", // 类型
"_id": "1",
"_version": 1, // 当前版本,以后每次更新版本都会加一
"result": "created", // 如果已存在,则会成为update
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"created": true // 是否创建
}
删除
delete /dev/emp/4
{
"found": true, // 是否存在
"_index": "dev",
"_type": "emp",
"_id": "1",
"_version": 14,
"result": "deleted", // 已删除
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
}
}
查询
get /<index>/<type>/<conditions>
指定id
get /dev/emp/1
{
"_index": "dev", // 索引
"_type": "emp", // 类型
"_id": "1", //id
"_version": 8, // 版本
"found": true, // 是否存在
"_source": { // 文档
"name": "zhou",
"email": "zz.mark06@gmail.com",
"info": {
"age": 24,
"height": 77
},
"join_date": "2017/11/03"
}
}
_search
_search
会显示这个类型的10条数据(默认只显示10条)
可以添加条件
简单使用:
get /dev/emp/_search?q=email:”u@abc.com”
q: query-string
这个查询等同于下面的那个。结果已去掉一些目前不重要的数据
{
"took": 15, // 请求消耗时间
"timed_out": false, // 是否超时
"hits": {
"total": 1, // 命中总数
"max_score": 1.2438203, // 最大匹配程度
"hits": [
{
"_score": 1.2438203, // 匹配程度
"_source": {
"name": "王小明",
"email": "wangxm@abc.com",
......
}
}
]
}
}
复杂使用:
有两种查询,queryDSL和filters,这里使用query
query查询会评估匹配程度,得出一个_score
,即全文搜索,
filter过滤器则很简单粗暴,只有符合与不符合,这与传统数据库相同
match
基本查询,会从前、后分别匹配
GET /dev/emp/_search
{
"query" : {
"match" : {
"email": "u@abc.com"
}
}
}
这个例子中,如果删除后面的m,则会匹配不到,如果将条件改写成这样
"email": "@abc.com @gmail.com"
那就会查询到两种邮箱后缀的条目
GET /dev/emp/_search
{
"query" : {
"bool": {
"must": [{
"match" : {
"email": "@gmail.com"
}
}],
"filter": {
"range": {
"info.age": {
"gte": 21,
"lte": 22
}
}
}
}
}
}
复杂些的组合查询
bool过滤器,内部需要使用must
、must_not
来修饰子查询
range范围过滤器,gte: great than (不准确)
数据聚合
类似于 group by
,可以统计数据
GET /dev/emp/_search
{
"query" : {
"match" : {
"email": "@abc.com @gmail.com"
}
},
"aggs": { // 聚合,数据来源于上面的查询,也可以省略上面查询变成全type聚合
"NAME": { // 本次聚合的名称
"terms": { // 过滤器类型
"field": "info.age",
"size": 10
},
"aggs": { // 子聚合,这东西可以嵌套,这里求了info.height的平均值
"avg_height": {
"avg": {
"field": "info.height"
}
}
}
}
}
}
{
"aggregations": {
"NAME": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 22,
"doc_count": 4,
"avg_height": {
"value": 75
}
},
{
"key": 21,
"doc_count": 3,
"avg_height": {
"value": 71.33
}
}
]
}
}
}
检测文档是否存在
head /dev/emp/1
HTTP 200 存在
HTTP 404 不存在
批量操作
_bulk方法
POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }}
{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
{ "doc" : {"title" : "My updated blog post"}}
只支持上述四种操作
好,转载结束,该自己动手实践了。
网友评论