Elasticsearch-41-实战案例-terms搜索多个值及搜索结果优化

之前的几个案例中都是用的term用来搜索. 本文使用terms来搜索数据

terms,就相当于sql中的in

准备工作

为帖子添加tag字段

1
2
3
4
5
6
7
8
9
POST /forum/article/_bulk
{ "update": { "_id": "1"} }
{ "doc" : {"tag" : ["java", "hadoop"]} }
{ "update": { "_id": "2"} }
{ "doc" : {"tag" : ["java"]} }
{ "update": { "_id": "3"} }
{ "doc" : {"tag" : ["hadoop"]} }
{ "update": { "_id": "4"} }
{ "doc" : {"tag" : ["java", "elasticsearch"]} }

terms搜索

需求一

搜索articleID为KDKE-B-9947-#kL5或QQPX-R-3956-#aD8的帖子

将需求转为sql就是:

1
2
3
SELECT * FROM forum.article 
where
id in ('KDKE-B-9947-#kL5','QQPX-R-3956-#aD8')

然后在es中去构建搜索条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET /forum/article/_search
{
"query": {
"constant_score": {
"filter": {
"terms": {
"articleID": [
"KDKE-B-9947-#kL5",
"QQPX-R-3956-#aD8"
]
}
}
}
}
}

需求二

搜索tag中包含java的帖子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
GET /forum/article/_search
{
"query": {
"constant_score": {
"filter": {
"terms": {
"tag": [
"java"
]
}
}
}
}
}

返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{
"took": 3,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 3,
"max_score": 1,
"hits": [
{
"_index": "forum",
"_type": "article",
"_id": "2",
"_score": 1,
"_source": {
"articleID": "KDKE-B-9947-#kL5",
"userID": 1,
"hidden": false,
"postDate": "2017-01-02",
"tag": [
"java"
]
}
},
{
"_index": "forum",
"_type": "article",
"_id": "4",
"_score": 1,
"_source": {
"articleID": "QQPX-R-3956-#aD8",
"userID": 2,
"hidden": true,
"postDate": "2017-01-02",
"tag": [
"java",
"elasticsearch"
]
}
},
{
"_index": "forum",
"_type": "article",
"_id": "1",
"_score": 1,
"_source": {
"articleID": "XHDK-A-1293-#fJ3",
"userID": 1,
"hidden": false,
"postDate": "2017-01-01",
"tag": [
"java",
"hadoop"
]
}
}
]
}
}

从结果上看的话,tag的值中只要包含了java就被搜索出来了

优化搜索结果

上面一个搜索中只要包含了java的数据都被搜索出来了,现在我们想搜索只包含java的数据

首先,我们需要修改一下数据,增加一个tag_cnt的字段

1
2
3
4
5
6
7
8
9
POST /forum/article/_bulk
{ "update": { "_id": "1"} }
{ "doc" : {"tag_cnt" : 2} }
{ "update": { "_id": "2"} }
{ "doc" : {"tag_cnt" : 1} }
{ "update": { "_id": "3"} }
{ "doc" : {"tag_cnt" : 1} }
{ "update": { "_id": "4"} }
{ "doc" : {"tag_cnt" : 2} }

执行完毕后,再次来构建搜索条件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
GET /forum/article/_search
{
"query": {
"constant_score": {
"filter": {
"bool": {
"must":[
{
"term":{
"tag_cnt":1
}
},
{
"terms":{
"tag":["java"]
}
}
]
}
}
}
}
}

返回值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "forum",
"_type": "article",
"_id": "2",
"_score": 1,
"_source": {
"articleID": "KDKE-B-9947-#kL5",
"userID": 1,
"hidden": false,
"postDate": "2017-01-02",
"tag": [
"java"
],
"tag_cnt": 1
}
}
]
}
}

总结

  • 掌握terms多值搜索
  • 优化terms多值搜索结果
  • terms相当于sql中的in