1. 引言
项目已提交至Github,有兴趣的同学可以下载来看看:https://github.com/ylw-github/SpringBoot-ES-NetDisk-Demo
网盘搜索原理图:
本文主要做一个迷你版的网盘操作,具体的爬虫获取数据功能就不做了,主要做网盘搜索的功能,演示效果如下:
搜索之后
2. SpringBoot基于ES的网盘应用开发
2.1 数据准备
1.定义文档映射
DELETE /clouddisk PUT /clouddisk POST /clouddisk/_mapping/disk { "disk": { "properties": { "baiduaddres": { "type": "keyword" }, "browsetimes": { "type": "long" }, "collectiontime": { "type": "date" }, "describe": { "type": "text", "analyzer": "ik_smart" }, "filesize": { "type": "float" }, "name": { "type": "text", "analyzer": "ik_smart" }, "sharpeople": { "type": "keyword" }, "shartime": { "type": "date" }, "source": { "type": "keyword" } } } }
2.添加数据到ES,数据在项目中有,可以克隆下来看看:
2.2 代码
2.2.1 前端代码
页面实现search.ftl
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>网盘搜索引擎</title> <!-- 新 Bootstrap 核心 CSS 文件 --> <link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <!-- 可选的Bootstrap主题文件(一般不使用) --> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"></script> <!-- jQuery文件。务必在bootstrap.min.js 之前引入 --> <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.min.js"></script> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </head> <body style="display: block; margin: 0 auto; width: 50%; " > <div style="width:100%;height:60px;" align="center"> <h2 style="color:#985f0d;">网盘搜索引擎</h2> </div> <br/> <div align="center"> <span style="font-size: 18px;" >检索出${total}条数据,耗时:${time}毫秒</span> </div> <br/> <br/> <div class="bs-example" data-example-id="striped-table"> <table class="table table-bordered table-hover"> <thead> <tr> <th style="text-align:center;" scope="row">链接名称</th> <th style="text-align:center;">文件大小GB</th> <th style="text-align:center;">分享人</th> <th style="text-align:center;">云盘地址</th> </tr> </thead> <tbody> <#list page.content as p> <tr > <th style="text-align: left;" > <#if keyword??> ${p.name?replace(keyword, '<span style="color: red">${keyword}</span>')} <#else> ${p.name} </#if> </th> <th style="text-align: center;">${p.filesize}</th> <th style="text-align: center;">${p.sharpeople}</th> <th style="text-align: center;"><a href="${p.baiduaddres}">云盘地址</a> </th> </tr> </#list> </tbody> </table> <div style="font-size: 21px;"> <#list 1..totalPage as i> <#if keyword??> <a href="/search?keyword=${keyword}&page=${i-1}" >${i}</a> <#else> <a href="/search?page=${i-1}" >${i}</a> </#if> </#list> 页 </div> </div> </body> </html>
2.2.2 后端代码
1.新建maven项目SpringBoot-ES-NetDisk-Demo
2.添加maven依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.google.collections</groupId> <artifactId>google-collections</artifactId> <version>1.0-rc2</version> </dependency> <!-- springboot整合freemarker --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> </dependencies>
3.application信息:
spring: data: elasticsearch: ####集群名称 cluster-name: myes ####地址 cluster-nodes: 192.168.162.131:9300 freemarker: # 设置模板后缀名 suffix: .ftl # 设置文档类型 content-type: text/html # 设置页面编码格式 charset: UTF-8 # 设置页面缓存 cache: false # 设置ftl文件路径 template-loader-path: - classpath:/templates # 设置静态文件路径,js,css等 mvc: static-path-pattern: /static/**
4.实体类层
@Document(indexName = "clouddisk", type = "disk") public class CloudDiskEntity { private String id; // 名称 private String name; // 来源 private String source; // 描述 private String describe; // 分享时间 private Date shartime; // 浏览次数 private Long browsetimes; // 文件大小 private Double filesize; // 分享人 private String sharpeople; // 收录时间 private String collectiontime; // 地址 private String baiduaddres; //getter and setter...
5.repository层
public interface CloudDiskDao extends ElasticsearchRepository<CloudDiskEntity, String> { }
6.控制层
import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.MatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class CloudDiskController { @Autowired private CloudDiskDao cloudDiskDao; @RequestMapping("/search") public String search(String keyword, @PageableDefault(page = 0, value = 6) Pageable pageable, HttpServletRequest req) { Long startTime = System.currentTimeMillis(); // 查询所有的 BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); if (!StringUtils.isEmpty(keyword)) { // 模糊查询 一定要ik中文 MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("name", keyword); boolQuery.must(matchQuery); } Page<CloudDiskEntity> page = cloudDiskDao.search(boolQuery, pageable); req.setAttribute("page", page); // 计算查询总数 long total = page.getTotalElements(); req.setAttribute("total", page.getTotalElements()); // 计算分页数 int totalPage = (int) ((total - 1) / pageable.getPageSize() + 1); req.setAttribute("totalPage", totalPage); Long endTime = System.currentTimeMillis(); // 计算程序的耗时时间 req.setAttribute("time", endTime - startTime); req.setAttribute("keyword", keyword); return "search"; } }
7.启动类:
@SpringBootApplication @EnableElasticsearchRepositories(basePackages = "com.ylw.springboot.es") public class AppEs { public static void main(String[] args) { SpringApplication.run(AppEs.class, args); } }
2.2 启动测试
浏览器输入http://localhost:8080/search,可以看到网盘列表:
现在搜索卡卡西:http://localhost:8080/search?keyword=卡卡西,可以看到30ms就搜索出来了。