来自于 ElasticSearch 参考的 Getting started 章节
1. 样本数据
每个文档都有如下的形式 : 客户银行账户信息文档
{
"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"
}
样本数据下载 : github
2.加载样本数据
使用如下命令批量加载(在 account.json 文件所在目录执行该命令) :
E:\study\ES\accounts {git}
$ curl -XPOST "http://localhost:9200/bank/account/_bulk?pretty" --data-binary "@accounts.json"
查看当前集群下的所有 索引信息:
$ curl -XGET "localhost:9200/_cat/indices?v"
health status index pri rep docs.count docs.deleted store.size pri.store.size
yellow open customer 5 1 2 0 6.5kb 6.5kb
yellow open bank 5 1 1000 0 447.9kb 447.9kb
3. 查询 API (Search API)
运行查询的两种基本方式 :
★ 通过 Rest request URI 发送查询参数
查询所有的文档:
curl -XGET "http://localhost:9200/bank/_search?pretty&q=*"
响应(部分):
{
"took" : 184,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1000,
"max_score" : 1.0,
"hits" : [ {
"_index" : "bank",
"_type" : "account",
"_id" : "25",
"_score" : 1.0,
"_source" : {
"account_number" : 25,
"balance" : 40540,
"firstname" : "Virginia",
"lastname" : "Ayala",
"age" : 39,
"gender" : "F",
"address" : "171 Putnam Avenue",
"employer" : "Filodyne",
"email" : "virginiaayala@filodyne.com",
"city" : "Nicholson",
"state" : "PA"
}
}
.....
其中 :
-
took
– ES 执行查询的毫秒级时间
-
timed_out
– 查询是否超时 -
_shards
– 查询的片区数, 同时显示了成功以及失败的片区数 -
hits
– 查询结果 -
hits.total
– 符合查询条件的文档总数 -
hits.hits
– 查询结果的数组 (默认列出前10个文档) -
_score
andmax_score
- 匹配度的得分
★ 通过 Rest request body 发送查询参数 : 即 使用更可读的 Json 格式
查询所有文档 : 和上面的结果一样
GET /bank/_search?pretty -d
{
"query": {
"match_all":{}
}
}
4. 介绍 查询语言
ES 提供了一种 JSON 风格的 领域特定语言(domain-specific language) 来执行查询 ,即 Query DSL 。
除了之前提到过的 query 参数 ,我们还能传递其他参数改变查询结果 :
★ query : 查询体
★ size : 指定查询的条数 ,默认为 10
★ from : 开始位置 ,和 size 搭配达到分页效果 ,不包括首端 , 默认为 0。
★ sort : 排序
eg. 所有数据 按 balance 字段 降序排列 ,并取出第三个 和 第四个
GET /bank/_search?pretty -d
{
"query": {
"match_all":{}
},
"sort":{
"balance":{
"order":"desc"
}
},
"size": 2,
"from": 4
}
5. 执行 查询
★ 返回部分字段 : _source
默认情况下, 所有的查询结果都来自于 一个完整 JSON 文档的部分文档 。 返回的数据被称为 源(source), 即在查询结果中的 _source 字段 。如果 不希望所有的源文档的字段都返回 ,我们可以从 被返回的 源(source)只请求 部分字段 :
GET /bank/_search?pretty -d
{
"query": {
"match_all":{}
},
"_source":["city","balance"], //数组的形式
"size": 1
}
★ 匹配 查询 : match
查询出所有文档的 地址字段中 包含 mill 或者 lane 的 文档 (不区分大小写,ES 都会转成小写):
POST /bank/_search?pretty
{
"query": { "match": { "address": "mill lane" } }
}
★匹配短语 查询 : match_phrase
查询出所有文档的地址字段中 包含 "mill lane" 短语的文档 :
POST /bank/_search?pretty
{
"query": { "match_phrase": { "address": "mILL lane" } }
}
★ 匹配短语前缀 查询 : match_phrase_prefix
查询出所有文档的地址字段前缀为 "19" 的文档 :
POST /bank/_search?pretty -d
{
"query": {
"match_phrase_prefix": {
"address": "19"
}
}
}
★ 布尔条件查询 : bool must (and)| must_not (not) | should (or)
我们可以组合使用 must 、must_not 、should
查询出所有文档的地址字段中 既 包含 "mill" 又包含 "lane" 的文档 :
POST /bank/_search?pretty -d
{
"query": {
"bool": {
"must": [
{"match": {
"address": "mill"
}},
{"match": {
"address": "lane"
}}
]
}
}
}
6. 执行过滤
和 查询的区别是 :
查询 会计算每个文档的得分 ,得分越高 ,则匹配度越高
过滤 不会计算得分 ,不满足则过滤,满足则保留
POST /bank/_search?pretty -d
{
"query": {
"bool": {
"must": { "match_all": {} },
"filter": {
"range": {
"balance": {
"gte": 20000,
"lte": 30000
}
}
}
}
}
}'
7. 执行聚合
Aggregations 用于分组和统计数据 , 可以类比于数据库 SQL 中 的 group by .
ES 中的 聚合 可以在 执行查询并返回命中数据的同时 返回聚合结果 , 当然可以选择不返回 文档 ,即 size = 0
可以在 聚合中 再次使用 聚合 ,即内置聚合 。
按 state 字段分组 :
POST /bank/_search?pretty -d
{
"size": 0, //不返回命中的 文档
"aggregations":{ // 也可以使用 aggs 缩写
"stat_by_state":{ //起一个名字
"terms":{
"field":"state" //作用字段
}
}
}
}
部分响应如下 :
{
"took": 898,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1000,
"max_score": 0,
"hits": []
},
"aggregations": {
"stat_by_state": {
"doc_count_error_upper_bound": 4,
"sum_other_doc_count": 743,
"buckets": [
{
"key": "tx",
"doc_count": 30
},
{
"key": "md",
"doc_count": 28
}
...
按 state 字段分组 并且按 balance 平均值 降序排列 :
POST /bank/_search?pretty -d
{
"size": 0,
"aggs":{
"group_by_state":{
"terms":{
"field":"state",
"order":{
"avg_balance":"desc"
}
},
"aggs":{
"avg_balance":{
"avg":{
"field":"balance"
}
}
}
}
}
}
部分响应 :
{
"took": 112,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1000,
"max_score": 0,
"hits": []
},
"aggregations": {
"group_by_state": {
"doc_count_error_upper_bound": -1,
"sum_other_doc_count": 827,
"buckets": [
{
"key": "co",
"doc_count": 14,
"avg_balance": {
"value": 32460.35714285714
}
},
{
"key": "ne",
"doc_count": 16,
"avg_balance": {
"value": 32041.5625
}
},
{
"key": "az",
"doc_count": 14,
"avg_balance": {
"value": 31634.785714285714
}
}
.......