Elasticsearch学习笔记(三)

我们在上一篇中简单的讲了一些DSL的查询操作,这篇学习笔记中,继续记录一些DSL的操作。

短语搜索

如果我们用上一篇中的方法去搜索rock climbing得到的结果中可能有记录只包含rock或者只包含climbing。如果我想要记录的记录同时包含rockclimbing怎么办,只需用match_phrase替换match即可。

1
2
3
4
5
6
7
8
curl -XGET "http://localhost:9200/_search/?pretty" -d'
{
"query": {
"match_phrase": {
"about": "rock climbing"
}
}
}'

高亮搜索

如果我们拿到了搜索结果,想要在页面上显示,并且高亮我们匹配到的关键字。

1
2
3
4
5
6
7
8
9
10
11
12
13
curl -XGET "http://localhost:9200/_search/?pretty" -d'
{
"query": {
"match_phrase": {
"about": "rock climbing"
}
},
"highlight": {
"fields": {
"about": {}
}
}
}'

返回结果:

1
2
3
4
5
6
7
...
"highlight": {
"about": [
"I love to go <em>rock</em> <em>climbing</em>"
]
}
...

我们发现结果和之前的基本相同,但是多了一个highlight的字段,并用htmlem标签强调了我们的关键字。然后我们就可以针对em标签写相应的css来高亮我们的关键字了。

聚合

Elasticsearch提供聚合的功能,关键字是aggregations,类似sql中的group by

我们用一份官方的测试数据来学习聚合吧。

  • 下载数据

    1
    curl -O -L https://github.com/bly2k/files/blob/master/accounts.zip
  • 解压数据

    1
    unzip accounts.zip
  • 导入数据

    1
    2
    # 导入数据到Elasticsearch
    curl -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary @accounts.json
  • 确认导入成功

    1
    2
    # 查看索引情况
    curl 'localhost:9200/_cat/indices?v'

    输出:

    1
    2
    3
    4
    5
    6
    7
    # 索引bank就是我们插入的记录了,你可以看到,它有1000条记录
    health status index pri rep docs.count docs.deleted store.size pri.store.size
    green open .marvel-es-1-2016.04.15 1 1 59598 126 38.9mb 19.5mb
    green open bank 5 1 1000 0 949.9kb 484.9kb
    green open megacorp 5 1 11 0 88.6kb 44.3kb
    green open .marvel-es-data-1 1 1 12 42 23.2kb 11.7kb
    green open test 5 1 1 0 7.4kb 3.7kb

这是一份虚拟的银行账户信息,我们通过一条记录来看看数据的schema:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"_index": "bank",
"_type": "account",
"_id": "44",
"_score": 1,
"_source": {
"account_number": 44, # 客户编号
"balance": 34487, # 余额
"firstname": "Aurelia", # 姓
"lastname": "Harding", # 名
"age": 37, # 年龄
"gender": "M", # 性别
"address": "502 Baycliff Terrace", # 家庭地址
"employer": "Orbalix", # 雇主
"email": "aureliaharding@orbalix.com", # 邮箱
"city": "Yardville", # 城市
"state": "DE" # 州
}
}

既然我们已经有了数据,就让我们开始聚合吧。

男女比例

1
2
3
4
5
6
7
8
9
10
curl -XGET "http://localhost:9200/bank/account/_search" -d'
{
"aggs": {
"gender": {
"terms":{
"field": "gender"
}
}
}
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
"aggregations": {
"gender": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "m",
"doc_count": 507
},
{
"key": "f",
"doc_count": 493
}
]
}
}

男女的平均年龄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
curl -XGET "http://localhost:9200/bank/account/_search" -d'
{
"aggs": {
"gender": {
"terms": {
"field": "gender"
},
"aggs": {
"avg_age": {
"avg": {"field":"age"}
}
}
}
}
}'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
"aggregations": {
"gender": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "m",
"doc_count": 507,
"avg_age": {
"value": 30.027613412228796
}
},
{
"key": "f",
"doc_count": 493,
"avg_age": {
"value": 30.3184584178499
}
}
]
}
}

看完这两个例子,对聚合有个大概的了解吧,具体的后面的笔记中会详细讲解。