first commit
This commit is contained in:
359
专栏/ElasticSearch知识体系详解/04入门:查询和聚合的基础使用.md
Normal file
359
专栏/ElasticSearch知识体系详解/04入门:查询和聚合的基础使用.md
Normal file
@ -0,0 +1,359 @@
|
||||
|
||||
|
||||
因收到Google相关通知,网站将会择期关闭。相关通知内容
|
||||
|
||||
|
||||
04 入门:查询和聚合的基础使用
|
||||
入门:从索引文档开始
|
||||
|
||||
|
||||
索引一个文档
|
||||
|
||||
|
||||
PUT /customer/_doc/1
|
||||
{
|
||||
"name": "John Doe"
|
||||
}
|
||||
|
||||
|
||||
为了方便测试,我们使用kibana的dev tool来进行学习测试:
|
||||
|
||||
|
||||
|
||||
查询刚才插入的文档
|
||||
|
||||
|
||||
|
||||
学习准备:批量索引文档
|
||||
|
||||
|
||||
ES 还提供了批量操作,比如这里我们可以使用批量操作来插入一些数据,供我们在后面学习使用。
|
||||
|
||||
|
||||
使用批量来批处理文档操作比单独提交请求要快得多,因为它减少了网络往返。
|
||||
|
||||
|
||||
下载测试数据
|
||||
|
||||
|
||||
数据是index为bank,accounts.json 下载地址 (如果你无法下载,也可以clone ES的官方仓库 ,然后进入/docs/src/test/resources/accounts.json目录获取)
|
||||
|
||||
数据的格式如下
|
||||
|
||||
{
|
||||
"account_number": 0,
|
||||
"balance": 16623,
|
||||
"firstname": "Bradshaw",
|
||||
"lastname": "Mckenzie",
|
||||
"age": 29,
|
||||
"gender": "F",
|
||||
"address": "244 Columbus Place",
|
||||
"employer": "Euron",
|
||||
"email": "[email protected]",
|
||||
"city": "Hobucken",
|
||||
"state": "CO"
|
||||
}
|
||||
|
||||
|
||||
|
||||
批量插入数据
|
||||
|
||||
|
||||
将accounts.json拷贝至指定目录,我这里放在/opt/下面,
|
||||
|
||||
然后执行
|
||||
|
||||
curl -H "Content-Type: application/json" -XPOST "localhost:9200/bank/_bulk?pretty&refresh" --data-binary "@/opt/accounts.json"
|
||||
|
||||
|
||||
|
||||
查看状态
|
||||
|
||||
|
||||
[elasticsearch@VM-0-14-centos root]$ curl "localhost:9200/_cat/indices?v=true" | grep bank
|
||||
% Total % Received % Xferd Average Speed Time Time Time Current
|
||||
Dload Upload Total Spent Left Speed
|
||||
100 1524 100 1524 0 0 119k 0 --:--:-- --:--:-- --:--:-- 124k
|
||||
yellow open bank yq3eSlAWRMO2Td0Sl769rQ 1 1 1000 0 379.2kb 379.2kb
|
||||
[elasticsearch@VM-0-14-centos root]$
|
||||
|
||||
|
||||
查询数据
|
||||
|
||||
|
||||
我们通过kibana来进行查询测试。
|
||||
|
||||
|
||||
查询所有
|
||||
|
||||
match_all表示查询所有的数据,sort即按照什么字段排序
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"query": { "match_all": {} },
|
||||
"sort": [
|
||||
{ "account_number": "asc" }
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
相关字段解释
|
||||
|
||||
|
||||
took – Elasticsearch运行查询所花费的时间(以毫秒为单位)
|
||||
timed_out –搜索请求是否超时
|
||||
_shards - 搜索了多少个碎片,以及成功,失败或跳过了多少个碎片的细目分类。
|
||||
max_score – 找到的最相关文档的分数
|
||||
hits.total.value - 找到了多少个匹配的文档
|
||||
hits.sort - 文档的排序位置(不按相关性得分排序时)
|
||||
hits._score - 文档的相关性得分(使用match_all时不适用)
|
||||
|
||||
|
||||
分页查询(from+size)
|
||||
|
||||
本质上就是from和size两个字段
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"query": { "match_all": {} },
|
||||
"sort": [
|
||||
{ "account_number": "asc" }
|
||||
],
|
||||
"from": 10,
|
||||
"size": 10
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
指定字段查询:match
|
||||
|
||||
如果要在字段中搜索特定字词,可以使用match; 如下语句将查询address 字段中包含 mill 或者 lane的数据
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"query": { "match": { "address": "mill lane" } }
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
(由于ES底层是按照分词索引的,所以上述查询结果是address 字段中包含 mill 或者 lane的数据)
|
||||
|
||||
查询段落匹配:match_phrase
|
||||
|
||||
如果我们希望查询的条件是 address字段中包含 “mill lane”,则可以使用match_phrase
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"query": { "match_phrase": { "address": "mill lane" } }
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
多条件查询: bool
|
||||
|
||||
如果要构造更复杂的查询,可以使用bool查询来组合多个查询条件。
|
||||
|
||||
例如,以下请求在bank索引中搜索40岁客户的帐户,但不包括居住在爱达荷州(ID)的任何人
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{ "match": { "age": "40" } }
|
||||
],
|
||||
"must_not": [
|
||||
{ "match": { "state": "ID" } }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
must, should, must_not 和 filter 都是bool查询的子句。那么filter和上述query子句有啥区别呢?
|
||||
|
||||
查询条件:query or filter
|
||||
|
||||
先看下如下查询, 在bool查询的子句中同时具备query/must 和 filter
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"match": {
|
||||
"state": "ND"
|
||||
}
|
||||
}
|
||||
],
|
||||
"filter": [
|
||||
{
|
||||
"term": {
|
||||
"age": "40"
|
||||
}
|
||||
},
|
||||
{
|
||||
"range": {
|
||||
"balance": {
|
||||
"gte": 20000,
|
||||
"lte": 30000
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
两者都可以写查询条件,而且语法也类似。区别在于,query 上下文的条件是用来给文档打分的,匹配越好 _score 越高;filter 的条件只产生两种结果:符合与不符合,后者被过滤掉。
|
||||
|
||||
所以,我们进一步看只包含filter的查询
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"query": {
|
||||
"bool": {
|
||||
"filter": [
|
||||
{
|
||||
"term": {
|
||||
"age": "40"
|
||||
}
|
||||
},
|
||||
{
|
||||
"range": {
|
||||
"balance": {
|
||||
"gte": 20000,
|
||||
"lte": 30000
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
结果,显然无_score
|
||||
|
||||
|
||||
|
||||
聚合查询:Aggregation
|
||||
|
||||
|
||||
我们知道SQL中有group by,在ES中它叫Aggregation,即聚合运算。
|
||||
|
||||
|
||||
简单聚合
|
||||
|
||||
比如我们希望计算出account每个州的统计数量, 使用aggs关键字对state字段聚合,被聚合的字段无需对分词统计,所以使用state.keyword对整个字段统计
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"group_by_state": {
|
||||
"terms": {
|
||||
"field": "state.keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
因为无需返回条件的具体数据, 所以设置size=0,返回hits为空。
|
||||
|
||||
doc_count表示bucket中每个州的数据条数。
|
||||
|
||||
嵌套聚合
|
||||
|
||||
ES还可以处理个聚合条件的嵌套。
|
||||
|
||||
比如承接上个例子, 计算每个州的平均结余。涉及到的就是在对state分组的基础上,嵌套计算avg(balance):
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"group_by_state": {
|
||||
"terms": {
|
||||
"field": "state.keyword"
|
||||
},
|
||||
"aggs": {
|
||||
"average_balance": {
|
||||
"avg": {
|
||||
"field": "balance"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
对聚合结果排序
|
||||
|
||||
可以通过在aggs中对嵌套聚合的结果进行排序
|
||||
|
||||
比如承接上个例子, 对嵌套计算出的avg(balance),这里是average_balance,进行排序
|
||||
|
||||
GET /bank/_search
|
||||
{
|
||||
"size": 0,
|
||||
"aggs": {
|
||||
"group_by_state": {
|
||||
"terms": {
|
||||
"field": "state.keyword",
|
||||
"order": {
|
||||
"average_balance": "desc"
|
||||
}
|
||||
},
|
||||
"aggs": {
|
||||
"average_balance": {
|
||||
"avg": {
|
||||
"field": "balance"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
结果
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user