接下来处理精确查询的功能部分。
如果使用上一章节的模糊查询来搜索John Smith,可以发现包含Smith的两个作者都会匹配到。这里既然是做精确查询,是假定只有John Smith会被匹配,而不会命中Jane Smith,这就要用到Term Query。
下面的开始日期和结束日期、点赞数范围分别是对日期类型和整数类型的范围搜索,这里可以用Range Query。
最后,当同时输入多个条件时,还需要用Bool查询把多个条件组合在一起。
因为条件比较多,首先编写一个Java Bean用来传递参数。
1
2
3
4
5
6
7
8
9
10 1public class SearchForm {
2
3 private int type;
4 private String keyword;
5 private String author;
6 private String startDate;
7 private String endDate;
8 private String minLikes;
9 private String maxLikes;
10
用type=0表示使用了模糊查询,type=1表示使用了精确查询。controller代码修改如下:
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 1 @RequestMapping("/blogs")
2 public String query(Model model, SearchForm searchForm, Integer pageNum, Integer pageSize) {
3
4 if(pageNum == null || pageNum <= 0)
5 pageNum = 1;
6 if(pageSize == null || pageSize <= 0)
7 pageSize = 5;
8
9 SearchQuery searchQuery = null;
10 if(searchForm.getType() == 0) {
11 //略
12 } else {
13 BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
14 if(StringUtils.isNotBlank(searchForm.getAuthor())) {
15 queryBuilder.must(QueryBuilders.termQuery("author.keyword", searchForm.getAuthor()));
16 }
17 if(StringUtils.isNotBlank(searchForm.getStartDate()) || StringUtils.isNotBlank(searchForm.getEndDate())) {
18 RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("date");
19 if(StringUtils.isNotBlank(searchForm.getStartDate())) {
20 rangeQueryBuilder = rangeQueryBuilder.gte(parseDate(searchForm.getStartDate()).getTime());
21 }
22 if(StringUtils.isNotBlank(searchForm.getEndDate())) {
23 rangeQueryBuilder = rangeQueryBuilder.lte(parseDate(searchForm.getEndDate()).getTime());
24 }
25 queryBuilder.must(rangeQueryBuilder);
26 }
27 if(StringUtils.isNotBlank(searchForm.getMinLikes()) || StringUtils.isNotBlank(searchForm.getMaxLikes())) {
28 RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("likes");
29 if(StringUtils.isNotBlank(searchForm.getMinLikes())) {
30 int minLikes = NumberUtils.toInt(searchForm.getMinLikes());
31 rangeQueryBuilder = rangeQueryBuilder.gte(minLikes);
32 }
33 if(StringUtils.isNotBlank(searchForm.getMaxLikes())) {
34 int maxLikes = NumberUtils.toInt(searchForm.getMaxLikes());
35 rangeQueryBuilder = rangeQueryBuilder.lte(maxLikes);
36 }
37 queryBuilder.must(rangeQueryBuilder);
38 }
39 searchQuery = new NativeSearchQueryBuilder()
40 .withPageable(new QPageRequest(pageNum - 1, pageSize))
41 .withQuery(queryBuilder)
42 .withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
43 .build();
44 }
45
46 Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class, new HighlightResultMapper());
47 model.addAttribute("blogs", blogs.getContent());
48 model.addAttribute("pageHelper", new PageHelper<>(blogs, pageNum, pageSize));
49 model.addAttribute("searchForm", searchForm);
50 return "index";
51 }
52
页面上增加精确查询按钮的点击事件及其他适配searchForm的调整。
1
2
3
4
5 1 $('#boolQuery').click(function () {
2 $('#type').val(1);
3 $('#searchForm').submit();
4 });
5
- 修改文档
页面上最后一个功能是点赞,点赞数+1需要修改文档,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13 1 @RequestMapping("/like")
2 @ResponseBody
3 public String like(int id) {
4 GetQuery getQuery = new GetQuery();
5 getQuery.setId(String.valueOf(id));
6 Blog blog = elasticsearchTemplate.queryForObject(getQuery, Blog.class);
7 blog.setLikes(blog.getLikes() + 1);
8
9 IndexQuery indexQuery = new IndexQueryBuilder().withId(String.valueOf(blog.getId())).withObject(blog).build();
10 elasticsearchTemplate.index(indexQuery);
11 return "OK";
12 }
13
页面代码:
1
2
3
4
5
6
7 1 function like(id) {
2 $.ajax({url:"/like?id=" + id,async:false});
3 var likes = $('#likes' + id).html();
4 likes++;
5 $('#likes' + id).html(likes);
6 }
7
源码
链接:https://pan.baidu.com/s/1NId5NTmmc1D99n_HgzF6BA
提取码:vwax