Elasticsearch文书档案查询,通过Elasticsearch使用的您

2019-05-16 作者:数据库   |   浏览(115)

Elasticsearch 系列导航

  • Elasticsearch快速入门 第1篇:Elasticsearch入门
  • Elasticsearch快速入门 第2篇:Elasticsearch和Kibana安装
  • Elasticsearch快速入门 第3篇:Elasticsearch索引和文档操作
  • Elasticsearch快速入门 第4篇:Elasticsearch文档查询

elasticsearch 与 elasticsearch-head 的安装

简单数据集

到目前为止,已经了解了基本知识,现在我们尝试用更逼真的数据集,这儿已经准备好了一份虚构的JSON,关于客户银行账户信息的。每个文档的结构如下:

{
    "account_number": 0,
    "balance": 16623,
    "firstname": "Bradshaw",
    "lastname": "Mckenzie",
    "age": 29,
    "gender": "F",
    "address": "244 Columbus Place",
    "employer": "Euron",
    "email": "bradshawmckenzie@euron.com",
    "city": "Hobucken",
    "state": "CO"
}

出于好奇,我从www.json-generator.com/生成了这些数据,请忽略数据的实际值和语义,因为这些都是随机生成的。

ElasticSearch Index API && Mapping

加载样本数据集

可以从这里下载示例数据集(accounts.json),解压到当前目录,然后用以下方式把它加载到集群中

curl -H "Content-Type: application/json" -XPOST 'localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json"
curl 'localhost:9200/_cat/indices?v'

返回内容如下:

health status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   .kibana XYZPR5XGQGWj8YlyZ1et_w   1   1          1            0      3.1kb          3.1kb
yellow open   bank    uoTQIb3GSDOH08CmsIy66A   5   1        999            0    639.5kb        639.5kb

这意味着我们已经成功批量索引999个文档到bank索引下(类型为account )。

注意,上面的操作不能在kibana中执行,需要使用curl

具体操作是,把下载的json文档放在和curl.exe相同的目录,然后打开命令提示符定位到curl.exe所在目录,然后粘贴以下命令(我的curl版本是7.53.1,需要改成下面的方式才能执行成功),回车即可

curl -H "Content-Type: application/json" -XPOST localhost:9200/bank/account/_bulk?pretty --data-binary "@accounts.json"

在ElasticSearch中使用 IK 中文分词插件

查询API

运行查询有两种方式,一是通过 REST request URI 方式发送查询参数,二是通过 REST request body 。方式二更为灵活,可以使用可读性好的JSON 格式定义你的查询条件,下面我们针对方式一举个例子,以后的教程都使用方式二。

REST API的查询条件放在_search之后,以下例子返回 bank 索引中的所有文档:

GET /bank/_search?q=*&sort=account_number:asc&pretty

bank 表示查询bank索引中的文档, _search 后面跟的是查询条件,q=* 参数指示 Elasticsearch 匹配索引中的所有文档。 sort=account_number:asc 参数指示使用 account_number 对结果进行升序排序。 pretty 参数告诉 Elasticsearch 返回漂亮的JSON结果。

返回部分内容如下:

{
  "took" : 63,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : null,
    "hits" : [ {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "0",
      "sort": [0],
      "_score" : null,
      "_source" : {"account_number":0,"balance":16623,"firstname":"Bradshaw","lastname":"Mckenzie","age":29,"gender":"F","address":"244 Columbus Place","employer":"Euron","email":"bradshawmckenzie@euron.com","city":"Hobucken","state":"CO"}
    }, {
      "_index" : "bank",
      "_type" : "account",
      "_id" : "1",
      "sort": [1],
      "_score" : null,
      "_source" : {"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
    }, ...
    ]
  }
}

至于返回内容,我们看到以下部分:

  • took -  Elasticsearch  执行查询的时间(以毫秒为单位)
  • timed_out - 告诉我们查询是否超时
  • _shards - 告诉我们查询了多少个分片,以及查询成功/失败的分片数量
  • hits - 查询结果
  • hits.total - 符合我们查询条件的文档总数
  • hits.hits - 实际查询结果数组(默认为前10个文档)
  • hits.sort - 对结果进行排序的键(如果没提供,则默认使用_score进行排序)
  • hits._scoremax_score-现在先忽略这些字段

使用方式二执行上面查询如下

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": [
    { "account_number": "asc" }
  ]
}

不同点是我们用json格式的请求体代替了_search api uri中的q=*参数。我们将会在后面的内容讨论json格式的查询。

ElasticSearch 基本概念

注意,当我们接收到返回结果的时候, elasticsearch 已经完全处理了这个请求,不会维护任何的服务器端的资源或者在结果中打开游标。这与许多其他的平台形成鲜明的对比(比如sql的游标)

Nest客户端的基本使用方法

查询语言介绍

 Elasticsearch  t提供了一种 JSON-style 的特定领域语言用来执行查询,称为 Query DSL,该查询语言十分全面,初看可能觉得有点吓人。事实上,学习它的最好方式就是从几个基本的例子开始。回到上一个例子,我们执行了这个查询:

GET /bank/_search
{
  "query": { "match_all": {} }
}

上面的 query   部分告诉我们查询定义是什么,  match_all 部分仅仅是我们想运行的查询的类型,也就是查询指定索引下的所有文档。

除了查询参数以外,也可以通过其他参数影响查询结果。比如前面的 sort 指定排序字段,下面通过 size 指定返回结果数

GET /bank/_search
{
  "query": { "match_all": {} },
  "size": 1
}

持续更新中

注意 size 如果不指定,默认是10。

下面的例子匹配所有,并且返回第11到20之间的文档

GET /bank/_search
{
  "query": { "match_all": {} },
  "from": 10,
  "size": 10
}

 from参数(最小值是0,不是1)指定返回文档的起始文档的索引, size 参数指定一共返回多少个文档。这个特性对实现分页非常有用。如果 from 没有指定,默认值是0。

下面的例子匹配所有,并且通过 balance 字段对结果进行降序排序,返回前10条(默认 size )文档。

GET /bank/_search
{
  "query": { "match_all": {} },
  "sort": { "balance": { "order": "desc" } }
}

 

执行查询

接下来我们进一步探讨Query DSL。首先看一下返回的文档字段。默认情况下,完整的JSON文档作为所有搜索的一部分返回。

默认情况下,完整的JSON文档作为所有搜索的一部分返回。文档原始内容被称为源(查询结果中的_source字段)。如果不希望返回整个源文档,也可以请求仅几个字段被返回。

以下示例显示如何返回两个字段(_source内), account_number 和 balance :

GET /bank/_search
{
  "query": { "match_all": {} },
  "_source": ["account_number", "balance"],
  "size": 1

}

返回内容如下:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 999,
    "max_score": 1,
    "hits": [
      {
        "_index": "bank",
        "_type": "account",
        "_id": "25",
        "_score": 1,
        "_source": {
          "account_number": 25,
          "balance": 40540
        }
      }
    ]
  }
}

以上的例子仅仅减少了 _source 里的字段,返回的字段 account_number 和 balance 仍然包含在 _source 中

如果你之前有SQL背景,上述在概念上与SQL SELECT FROM字段列表有些相似。

现在来看看查询部分。通过前面的示例,我们已经学会了如何使用 match_all 查询来匹配所有文档。现在介绍一个名为match查询的新查询,可以将其视为基本的字段搜索查询(即针对特定字段或一组字段进行搜索)。

以下示例返回的 account_number 为20:

GET /bank/_search
{
  "query": { "match": { "account_number": 20 } }
}

返回结果:

{
  "took": 15,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1,
    "hits": [
      {
        "_index": "bank",
        "_type": "account",
        "_id": "20",
        "_score": 1,
        "_source": {
          "account_number": 20,
          "balance": 16418,
          "firstname": "Elinor",
          "lastname": "Ratliff",
          "age": 36,
          "gender": "M",
          "address": "282 Kings Place",
          "employer": "Scentric",
          "email": "elinorratliff@scentric.com",
          "city": "Ribera",
          "state": "WA"
        }
      }
    ]
  }
}

以下实例返回 address 中包含"mill"的所有账户:

GET /bank/_search
{
  "query": { "match": { "address": "mill" } }
}

以下示例返回address中包含"mill"或者"lane"的所有账户:

GET /bank/_search
{
  "query": { "match": { "address": "mill lane" } }
}

以下示例是matchmatch_phrase)的一个变体,返回在地址中包含短语"mill lane"的所有帐户:

GET /bank/_search
{
  "query": { "match_phrase": { "address": "mill lane" } }
}

下面介绍bool(ean) query 。 布尔查询允许我们把多个 match 查询合并到一个查询中。

以下示例由两个 match  查询组成,返回 address 中既包含"mill" 又包含"lane" 的所有账户:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

在上面的示例中, bool must 里面的所有查询条件必须都为真时才会被匹配。

相比之下,下面的示例由两个match查询组成,并返回在地址中包含"mill"或"lane"的所有帐户:

GET /bank/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

在上面的例子中, bool should 子句指定了一个查询列表,只要其中一个查询为真,文档就会被匹配。

以下示例由两个match查询组成,并返回在地址中既不包含"mill"也不包含"lane"的所有帐户:

GET /bank/_search
{
  "query": {
    "bool": {
      "must_not": [
        { "match": { "address": "mill" } },
        { "match": { "address": "lane" } }
      ]
    }
  }
}

在上面的例子中,bool must_not 子句指定一个查询列表,只有查询列表中的条件都为假的时候才会被匹配。

也可以把 must,should,must_not 同时组合到bool子句。此外,我们也可以组合bool 到任何一个bool子句中,实现复杂的多层bool子句嵌套逻辑。

下面的例子返回所有年龄是40岁但不居住在ID(Idaho)的账户:

GET /bank/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "age": "40" } }
      ],
      "must_not": [
        { "match": { "state": "ID" } }
      ]
    }
  }
}

 正文

执行过滤

前面我们跳过了一点细节,文档得分(也就是在搜索结果中的 _score 字段)。分数是一个数值,它是文档与我们指定的搜索查询匹配的相对度量。分数越高,文档越相关,分数越低,文档的相关性越低。但查询并不总是需要产生分数,特别是当它们仅用于"过滤"文档集时。 Elasticsearch 会检测这些情况,并自动优化查询执行,以免计算无用的分数。

bool查询支持filter子句,它允许你使用一个查询语句去限制其它子句的匹配结果,同时不会计算文档的得分。例如,我们来介绍一下``` [range` query](), 它允许我们通过一个范围值去过滤文档。通常用于数字或日期过滤。

以下示例使用布尔查询返回余额在20000到30000之间(包括端值)的所有帐户。换句话说,我们想找到余额大于或等于20000且小于等于30000的账户。

GET /bank/_search
{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

仔细分析上面的例子,bool查询包含了一个match_all查询(查询部分)和一个range查询(过滤部分)。我们也可以用任何其它的查询语句代替查询和过滤部分的语句。对于上面的例子,因为所有文档都是指定范围之内的,他们从某种意义上来说是等价的(equally),即他们的相关度都是一样的(filter子句查询,不会改变得分)。

除了 match_all,match,bool,range查询,还有很多种类的查询,但我们不在这里一一介绍。从现在开始,我们对查询已经有一个基础的了解,把学到的知识应用到其他查询类型应该也没什么难度。

假设你已经有一份数据保存在Elasticsearch里,类似于下面这种schema,如果没有参考导入测试数据

执行聚合

聚合提供从数据中分组和提取统计信息的功能。理解聚合的最简单的方法是将其大致等同于SQL GROUP BY和SQL聚合函数。在 Elasticsearch 中,可以返回匹配搜索的同时返回聚合结果,在一个响应中将所有匹配的结果和聚合结果同时返回。这是非常强大和高效的,可以降低网络请求的次数。

以下示例通过state字段进行分组,并按照count 降序排序,返回前10(默认值)条数据:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

在SQL中,上述聚合在概念上类似于:

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC

返回内容(仅部分)如下:

{
  "took": 50,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 999,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_state": {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets": [
        {
          "key": "ID",
          "doc_count": 27
        },
        {
          "key": "TX",
          "doc_count": 27
        },
        {
          "key": "AL",
          "doc_count": 25
        },
        {
          "key": "MD",
          "doc_count": 25
        },
        {
          "key": "TN",
          "doc_count": 23
        },
        {
          "key": "MA",
          "doc_count": 21
        },
        {
          "key": "NC",
          "doc_count": 21
        },
        {
          "key": "ND",
          "doc_count": 21
        },
        {
          "key": "MO",
          "doc_count": 20
        },
        {
          "key": "AK",
          "doc_count": 19
        }
      ]
    }
  }
}

可以看到,有27个账户居住在ID(Idaho),27个账户居住在TX(Texas),25个账户居住在AL(Alabama)等等。

注意,设置size=0 是为了不显示搜索结果,因为我们仅仅想看返回的聚合结果。

基于上述例子,下面的例子除了分组还会计算每个州的账户的平均余额:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

返回内容(仅部分)如下:

{
  "took": 32,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 999,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_state": {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets": [
        {
          "key": "ID",
          "doc_count": 27,
          "average_balance": {
            "value": 24368.777777777777
          }
        },
        {
          "key": "TX",
          "doc_count": 27,
          "average_balance": {
            "value": 27462.925925925927
          }
        },
        {
          "key": "AL",
          "doc_count": 25,
          "average_balance": {
            "value": 25739.56
          }
        },
        {
          "key": "MD",
          "doc_count": 25,
          "average_balance": {
            "value": 24963.52
          }
        },
        {
          "key": "TN",
          "doc_count": 23,
          "average_balance": {
            "value": 29796.782608695652
          }
        },
        {
          "key": "MA",
          "doc_count": 21,
          "average_balance": {
            "value": 29726.47619047619
          }
        },
        {
          "key": "NC",
          "doc_count": 21,
          "average_balance": {
            "value": 26785.428571428572
          }
        },
        {
          "key": "ND",
          "doc_count": 21,
          "average_balance": {
            "value": 26303.333333333332
          }
        },
        {
          "key": "MO",
          "doc_count": 20,
          "average_balance": {
            "value": 24151.8
          }
        },
        {
          "key": "AK",
          "doc_count": 19,
          "average_balance": {
            "value": 24088.63157894737
          }
        }
      ]
    }
  }
}

注意我们是如何把average_balance聚合嵌入到group_by_state聚合中的。在所有的聚合中这是一种普遍的模式。你可以按你的需求随意的在聚合中嵌套聚合子句,汇总你的数据。

基于上面的例子,以下示例加入了按每个州的账户平均余额降序排序:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword",
        "order": {
          "average_balance": "desc"
        }
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

以下示例演示了如何按年龄段(20-29岁,30-39岁和40-49岁),然后按性别分组,然后最终得到每个年龄段的男女平均账户余额:

GET /bank/_search
{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

返回结果如下:

{
  "took": 21,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 999,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "group_by_age": {
      "buckets": [
        {
          "key": "20.0-30.0",
          "from": 20,
          "to": 30,
          "doc_count": 450,
          "group_by_gender": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "M",
                "doc_count": 231,
                "average_balance": {
                  "value": 27400.982683982686
                }
              },
              {
                "key": "F",
                "doc_count": 219,
                "average_balance": {
                  "value": 25341.260273972603
                }
              }
            ]
          }
        },
        {
          "key": "30.0-40.0",
          "from": 30,
          "to": 40,
          "doc_count": 504,
          "group_by_gender": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "F",
                "doc_count": 253,
                "average_balance": {
                  "value": 25670.869565217392
                }
              },
              {
                "key": "M",
                "doc_count": 251,
                "average_balance": {
                  "value": 24288.239043824702
                }
              }
            ]
          }
        },
        {
          "key": "40.0-50.0",
          "from": 40,
          "to": 50,
          "doc_count": 45,
          "group_by_gender": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
              {
                "key": "M",
                "doc_count": 24,
                "average_balance": {
                  "value": 26474.958333333332
                }
              },
              {
                "key": "F",
                "doc_count": 21,
                "average_balance": {
                  "value": 27992.571428571428
                }
              }
            ]
          }
        }
      ]
    }
  }
}

还有许多其他聚合功能,将不再详细介绍。如果您想进一步试验,聚合参考指南是一个很好的起点。

{
    "account_number": 0,
    "balance": 16623,
    "firstname": "Bradshaw",
    "lastname": "Mckenzie",
    "age": 29,
    "gender": "F",
    "address": "244 Columbus Place",
    "employer": "Euron",
    "email": "bradshawmckenzie@euron.com",
    "city": "Hobucken",
    "state": "CO"
}

结论

 elasticsearch 是一个既简单又复杂的产品。目前为止,我们已经学了如何使用REST API以及 elasticsearch 的基本概念和特性。希望这个教程可以让你很好的理解 elasticsearch ,更重要的是,激励你继续学习后续教程要介绍的强大特性。

官方文档

参考文档

 那么我们接下来就可以 过滤,搜索,聚合来获取到我们想要的数据。

Elasticsearch提供了一套Json风格的领域特定语言来帮助查询,被称为Query DSL.

搜索通过在URL结尾加_search来指定,具体查询提交通过Request Body来指定,

比如下面的Request Body:

query: 用来指定查询条件

from:从第几个开始取

size:取多少条记录,默认10条,比如这个例子有13条记录满足条件,但是只返回1条记录

sort:用来指定排序规则

图片 1

OK,通过刚才的实验,我们对查询有了一个基本的认识,下面让我们来继续认识更加有趣的查询:

  1. 减少返回字段的个数(默认情况下是返回一个文档的所有字段信息)

    {
      "query": { "match_all": {} },
      "_source": ["account_number", "balance"]
    }
    
  2. 返回account_number等于20的account

    {
      "query": { "match": { "account_number": 20 } }
    }
    

     match是一个模糊匹配,但是由于account_number是long类型,所以这里当做精确匹配来过滤

  3. 返回**address字段中包含mill的account**

    {
      "query": { "match": { "address": "mill" } }
    }
    

     由于address是text类型,所以这里说的是包含mill而不是等于mill.

  4. 返回address字段中包含"mill" 或 "lane"的account

    {
      "query": { "match": { "address": "mill lane" } }
    }
    

     由于address是text类型,而且"mill lane"这里在查询的时候被当作两个词来分别进行查询

  5. 返回address字段中包含"mill lane"的account

     这里使用match_phrase(短语匹配)查询类型,把"mill lane"当作一个整体来查询

    {
      "query": { "match_phrase": { "address": "mill lane" } }
    }
    

     

  6. 返回address字段中同时包含"mill" 和 "lane"的account

    {
      "query": {
        "bool": {
          "must": [
            { "match": { "address": "mill" } },
            { "match": { "address": "lane" } }
          ]
        }
      }
    }
    

     这里使用了bool查询语句,它允许我们组合多个小的查询一起来完成稍微复杂的查询,bool must 要求所有子查询返回true,所有子查询之间可以理解为一个and的操作。

  7. 返回address字段中包含"mill" 或 "lane"的account

     bool should 要求子查询中的任一个满足条件,可以理解为或的关系

    {
      "query": {
        "bool": {
          "should": [
            { "match": { "address": "mill" } },
            { "match": { "address": "lane" } }
          ]
        }
      }
    }
    

     

  8. 返回address字段中既不包含"mill" 也不包含 "lane"的account

     bool must_not子句之间是或的关系

    {
      "query": {
        "bool": {
          "must_not": [
            { "match": { "address": "mill" } },
            { "match": { "address": "lane" } }
          ]
        }
      }
    }
    

     

  9. 返回年龄等于40 且不住在ID地区的account

    {  "query": {
        "bool": {
          "must": [
            { "match": { "age": "40" } }
          ],
          "must_not": [
            { "match": { "state": "ID" } }
          ]
        }
      }
    }
    

        我们可以同时联合must, should, and must_not子句在一个bool语句内,

         也可以继续在bool子句下面继续嵌套使用bool子句来完成更加复杂的查询需求。

 Filter 过滤

        在返回的结果中有一个_score字段,score是一个数值,表示查询条件和这个文档的相关度,分数越高,说明某个文档的相关度越高,

        反之,相关度越低,但是查询 并不总是产生分数,尤其当你使用过滤子句来过滤文档的时候,Elasticsearch会自动检测这些场景,

       自动优化查询,让他不要去计算无用的分数,之前我们使用的bool查询也支持filter子句,

        例如我们想获取账户余额大于等于20000 小于等于30000的账户信息

{
  "query": {
    "bool": {
      "must": { "match_all": {} },
      "filter": {
        "range": {
          "balance": {
            "gte": 20000,
            "lte": 30000
          }
        }
      }
    }
  }
}

 上面的这个例子其实挺好理解的,所有在这个range范围内的文档都具有相等的匹配度,

  没有哪一个文档比其他的文档匹配度更高,要么在这个范围内,要么不在,所以相关度是相等的,

 就没有必要再去计算这个score.

Aggregations聚合

聚合允许你给你的数据分组并获取他们的统计信息,你可以把它和SQL里面的goup by 以及SQL的聚合函数联系起来,

在Elasticsearch,你可以在一个响应里同时返回聚合信息和结果明细,

比如我们使用state来给所有的accounts分组,默认返回前10条聚合记录,顺序按照组内文档数量的倒序排列

{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      }
    }
  }
}

 你可以结合下面的SQL语句更好理解上面的语句

SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC
部分返回结果 如下显示:

{
  "took": 29,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits" : {
    "total" : 1000,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_state" : {
      "doc_count_error_upper_bound": 20,
      "sum_other_doc_count": 770,
      "buckets" : [ {
        "key" : "ID",
        "doc_count" : 27
      }, {
        "key" : "TX",
        "doc_count" : 27
      }, {
        "key" : "AL",
        "doc_count" : 25
      }, {
        "key" : "MD",
        "doc_count" : 25
      }, {
        "key" : "TN",
        "doc_count" : 23
      }, {
        "key" : "MA",
        "doc_count" : 21
      }, {
        "key" : "NC",
        "doc_count" : 21
      }, {
        "key" : "ND",
        "doc_count" : 21
      }, {
        "key" : "ME",
        "doc_count" : 20
      }, {
        "key" : "MO",
        "doc_count" : 20
      } ]
    }
  }
}

 你可以观察到,上面的聚合我们设置size=0,不去显示符合条件的原始记录,

因为我们这次仅仅需要聚合的结果信息,如果你也需要原始记录信息,那么你可以重新指定size的大小

下面这个例子我们来求余额的平均值

{
  "size": 0,
  "aggs": {
    "group_by_state": {
      "terms": {
        "field": "state.keyword"
      },
      "aggs": {
        "average_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

 返回如下的结果,可以看到这里我们在group_by_state里面嵌套使用了average_balance,这是一种比较通用的做法,

你可以在任意聚合内嵌套任意聚合来获取需要的统计信息。

图片 2

下面这个例子演示根据年龄组来分组,然后根据性别来分组最后求账户余额的平均值

{
  "size": 0,
  "aggs": {
    "group_by_age": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 20,
            "to": 30
          },
          {
            "from": 30,
            "to": 40
          },
          {
            "from": 40,
            "to": 50
          }
        ]
      },
      "aggs": {
        "group_by_gender": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "average_balance": {
              "avg": {
                "field": "balance"
              }
            }
          }
        }
      }
    }
  }
}

 下面是年龄组分组 计算聚合的部分返回结果:

 

图片 3

 

下面

 

本文由www.bifa365365.com发布于数据库,转载请注明出处:Elasticsearch文书档案查询,通过Elasticsearch使用的您

关键词: www.bifa3653