ElasticSearch实战(三) 空查询、分页

释放双眼,带上耳机,听听看~!

接下来实现读取数据并在网页上以列表形式显示的功能。首先添加一些测试数据:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
1List<IndexQuery> indexQueries = Arrays.asList(
2                new IndexQueryBuilder().withObject(new Blog(1, "Mary Jones", "Jane is an expert in her field", 80, parseDate("2019-06-21"))).build(),
3                new IndexQueryBuilder().withObject(new Blog(2, "Jane Smith", "I am starting to get the hang of this...", 0, parseDate("2019-06-20"))).build(),
4                new IndexQueryBuilder().withObject(new Blog(3, "John Smith", "The Query DSL is really powerful and flexible", 100, parseDate("2019-06-20"))).build(),
5                new IndexQueryBuilder().withObject(new Blog(4, "Mary Jones", "Still trying this out...", 0, parseDate("2019-06-20"))).build(),
6                new IndexQueryBuilder().withObject(new Blog(5, "Mary Jones", "However did I manage before Elasticsearch?", 200, parseDate("2019-06-19"))).build(),
7                new IndexQueryBuilder().withObject(new Blog(6, "Jane Smith", "I like to collect rock albums", 0, parseDate("2019-06-19"))).build(),
8                new IndexQueryBuilder().withObject(new Blog(7, "Douglas Fir", "I like to build cabinets", 50, parseDate("2019-06-19"))).build(),
9                new IndexQueryBuilder().withObject(new Blog(8, "John Smith", "I love to go rock climbing", 40, parseDate("2019-06-18"))).build(),
10                new IndexQueryBuilder().withObject(new Blog(9, "Mary Jones", "I am Mary Jones, welcome to my blog!", 500, parseDate("2019-06-17"))).build(),
11                new IndexQueryBuilder().withObject(new Blog(10, "Mary Jones", "My first blog entry", 400, parseDate("2019-06-17"))).build()
12        );
13        elasticsearchTemplate.bulkIndex(indexQueries);
14
  • 空查询

读取全部数据用matchAllQuery查询,controller代码:


1
2
3
4
5
6
7
8
9
10
11
12
13
1    @Autowired
2    private ElasticsearchTemplate elasticsearchTemplate;
3
4    @RequestMapping("/blogs")
5    public String query(Model model) {
6        SearchQuery searchQuery = new NativeSearchQueryBuilder()
7                .withQuery(QueryBuilders.matchAllQuery())
8                .build();
9        Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class);
10        model.addAttribute("blogs", blogs.getContent());
11        return "index";
12    }
13

页面代码同使用关系型数据库的方式完全相同,主要代码:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1<div class="post" th:each="blog,blogStat:${blogs}">
2  <div class="user-block">
3    <span class="username" style="margin-left: 0px">
4      <a href="#" th:utext="${blog.author}">Jonathan Burke Jr.</a>
5    </span>
6    <span class="description" style="margin-left: 0px"
7                                              th:text="${#dates.format(blog.date,'yyyy-MM-dd HH:mm:ss')}"></span>
8  </div>
9  <p th:utext="${blog.text}"></p>
10  <ul class="list-inline">
11    <li><a class="btn btn-default btn-xs" th:href="@{'javascript:like(\'' + ${blog.id} + '\')'}"><i class="fa fa-thumbs-o-up"></i> 点赞</a>
12    </li>
13    <li class="pull-right"><span th:id="likes + ${blog.id}" th:text="${blog.likes}"></span>赞</li>
14  </ul>
15</div>
16

效果如下:

ElasticSearch实战(三) 空查询、分页

  • 排序

继续添加按日期倒序排序功能,只需增加一行代码:


1
2
3
4
5
1        SearchQuery searchQuery = new NativeSearchQueryBuilder()
2                .withQuery(QueryBuilders.matchAllQuery())
3                .withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
4                .build();
5
  • 分页

创建一个分页辅助类:


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
63
64
65
66
67
1import org.springframework.data.domain.Page;
2
3import java.util.List;
4
5public class PageHelper<T> {
6
7    private long total;
8    private List<T> list;
9    private int pageNum;
10    private int pageSize;
11    private int pages;
12    private int previousPageNum;
13    private int nextPageNum;
14    private boolean previousPage;
15    private boolean nextPage;
16    private int[] navigatePageNums;
17
18    public PageHelper(Page<T> page, int pageNum, int pageSize) {
19
20        this.list = page.getContent();
21        this.total = page.getTotalElements();
22        this.pageNum = pageNum;
23        this.pageSize = pageSize;
24        this.pages = page.getTotalPages();
25        this.previousPage = false;
26        this.nextPage = false;
27
28        int startNum = 1;
29        int endNum = pages;
30        int navigateNums = 10; //导航栏显示数字个数
31        if (pages <= navigateNums) {
32        } else if ((pageNum + (navigateNums + 1) / 2) > pages) {
33            startNum = pages - (navigateNums - 1);
34            endNum = pages;
35        } else if (pageNum <= (navigateNums + 1) / 2) {
36            endNum = navigateNums;
37        } else {
38            if (navigateNums % 2 == 0) {
39                startNum = pageNum - navigateNums / 2;
40                endNum = pageNum + (navigateNums - 1) / 2;
41            } else {
42                startNum = pageNum - navigateNums / 2;
43                endNum = pageNum + navigateNums / 2;
44            }
45        }
46        this.navigatePageNums = new int[endNum - startNum + 1];
47        for (int i = startNum; i <= endNum; i++) {
48            this.navigatePageNums[i - startNum] = i;
49        }
50
51        for (int i = 0; i < this.pages; ++i) {
52            this.navigatePageNums[i] = i + 1;
53        }
54        if (this.pageNum > 1) {
55            this.previousPage = true;
56            this.previousPageNum = this.pageNum - 1;
57        }
58
59        if (this.pageNum < this.pages) {
60            this.nextPage = true;
61            this.nextPageNum = this.pageNum + 1;
62        }
63    }
64
65    //getter/setter略
66}
67

controller改造后如下:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1    @RequestMapping("/blogs")
2    public String query(Model model, 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 = new NativeSearchQueryBuilder()
10                .withPageable(new QPageRequest(pageNum - 1, pageSize))
11                .withQuery(QueryBuilders.matchAllQuery())
12                .withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
13                .build();
14        Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class);
15        model.addAttribute("blogs", blogs.getContent());
16        model.addAttribute("pageHelper", new PageHelper<>(blogs, pageNum, pageSize));
17        return "index";
18    }
19

创建一个展示层的分页组件,pagenation.html:


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
1<!DOCTYPE html>
2<html lang="en" xmlns:th="http://www.thymeleaf.org">
3<th:block th:fragment="formBase(pageInfo)">
4    <input type="hidden" id="pageNum" name="pageNum"/>
5    <div class="col-sm-6">
6        <div class="dataTables_length">
7            <label><select name="pageSize" class="form-inline input-sm" οnchange="javascript:page(1);">
8            <option value="5" th:selected="${pageInfo.pageSize == 5}">5</option>
9            <option value="10" th:selected="${pageInfo.pageSize == 10}">10</option>
10            <option value="20" th:selected="${pageInfo.pageSize == 20}">20</option>
11            <option value="50" th:selected="${pageInfo.pageSize == 50}">50</option>
12            <option value="100" th:selected="${pageInfo.pageSize == 100}">100</option>
13        </select> <th:block th:text="'条/页, 共' + ${pageInfo.total} + '条'"></th:block></label></div>
14    </div>
15    <div class="col-sm-6">
16        <div class="dataTables_filter" style="text-align: right">
17            <ul class="pagination pagination-sm no-margin">
18                <th:block th:if="${pageInfo.previousPage}">
19                    <li class="paginate_button previous"><a th:href="@{'javascript:page(' + ${pageInfo.previousPageNum} + ');'}"
20                                                            th:text="Previous"></a></li>
21                </th:block>
22                <th:block th:each="nav:${pageInfo.navigatePageNums}">
23                    <li th:class="${pageInfo.pageNum} == ${nav} ? 'paginate_button active' : 'paginate_button'"><a
24                            th:href="@{'javascript:page(' + ${nav} + ');'}" th:text="${nav}">1</a></li>
25                </th:block>
26                <th:block th:if="${pageInfo.nextPage}">
27                    <li class="paginate_button next"><a th:href="@{'javascript:page(' + ${pageInfo.nextPageNum} + ');'}"
28                                                        th:text="Next"></a></li>
29                </th:block>
30            </ul>
31        </div>
32    </div>
33    <script type="text/javascript">
34        function page(pageNum) {
35            document.getElementById("pageNum").value = pageNum;
36            document.forms[0].submit();
37        }
38    </script>
39</th:block>
40

在列表页引用该组件


1
2
3
4
1<div class="box-footer">
2  <th:block th:replace="pagenation::formBase(${pageHelper})"></th:block>
3</div>
4

重新运行后在页面底部显示分页栏:

ElasticSearch实战(三) 空查询、分页

 

 源码:

链接:https://pan.baidu.com/s/1CaQp5LrcWdLp0UXUPrPbKg 
提取码:t5qj 

给TA打赏
共{{data.count}}人
人已打赏
安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

安全运维

设计模式的设计原则

2021-12-12 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索