导入maven依赖
代码语言:javascript复制<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.6.1</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- ElasticSearch依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- Lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Thymeleaf依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- FastJSON依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<!-- JSoup依赖(解析网页) -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.2</version>
</dependency>
</dependencies>
将ElasticSerch注入到SpringBoot
代码语言:javascript复制@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")
)
);
return client;
}
}
将我们需要的数据封装为一个对象
代码语言:javascript复制@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content {
private String title;
private String img;
private String price;
}
service层
(爬取数据以及实现搜索)
代码语言:javascript复制@Service
public class ContentService {
@Resource
private RestHighLevelClient client;
/**
* @Author: Aaron
* @Description: 输入搜索条件后将数据解析存储到ES中,并返回插入是否成功
* @Date: 2020-05-17 15:01
* @param: keyword
* @return: java.lang.Boolean
**/
public Boolean parseContent(String keyword) throws IOException {
//1.使用JSoup解析网页获取数据
List<Content> contentList = new HtmlParseUtils().parseJD(keyword);
//2.判断索引是否存在
GetIndexRequest getIndexRequest = new GetIndexRequest("jd_goods");
boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
//3.如果索引不存在则创建jd_goods索引
if (!exists) {
CreateIndexRequest createIndexRequest = new CreateIndexRequest("jd_goods");
client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
}
//4.如果成功创建BulkRequest对象,并设置超时时间
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("2m");
for (int i = 0; i < contentList.size(); i ) {
bulkRequest.add(
new IndexRequest("jd_goods")
.source(JSON.toJSONString(contentList.get(i)), XContentType.JSON)
);
}
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
return !bulk.hasFailures();
}
/**
* @Author: Aaron
* @Description: 获取数据实现搜索功能
* @Date: 2020-05-17 15:24
* @param: keyword
* @param: pageNo
* @param: pageSize
* @return: List<Map < String, Object>>
**/
public List<Map<String, Object>> searchPage(String keyword, Integer pageNo,
Integer pageSize) throws IOException {
//1.分页合理化
if (pageNo < 1) {
pageNo = 1;
}
//2.创建搜索请求
SearchRequest searchRequest = new SearchRequest("jd_goods");
//3.构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//4.开启分页
searchSourceBuilder.from(pageNo);
searchSourceBuilder.size(pageSize);
//5.精准匹配
TermQueryBuilder termQuery = QueryBuilders.termQuery("title", keyword);
searchSourceBuilder.query(termQuery);
//6.关键字高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");//要高亮的属性
highlightBuilder.requireFieldMatch(false);//关闭多个高亮
highlightBuilder.preTags("<span style='color:red'>");//高亮的前缀
highlightBuilder.postTags("</span>");//高亮的后缀
searchSourceBuilder.highlighter(highlightBuilder);
//7.设置超时间60s
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//8.将我们的搜素条件放到请求当中
searchRequest.source(searchSourceBuilder);
//9.客户端执行搜索请求,返回搜索结果
SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
//10.将返回结果封装
List<Map<String, Object>> mapList = new ArrayList<>();
for (SearchHit hit : search.getHits().getHits()) {
//解析高亮的字段(将原来的字段换成我们新的高亮字段)
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField title = highlightFields.get("title");
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
if (null != title) {
Text[] fragments = title.fragments();
String newTitle = "";
for (Text fragment : fragments) {
newTitle = fragment;
}
sourceAsMap.put("title", newTitle);
}
mapList.add(sourceAsMap);
}
return mapList;
}
controller层
代码语言:javascript复制@RestController
public class ContentController {
@Resource
private ContentService contentService;
@GetMapping("/parseJD/{keyword}")
public Boolean parse(@PathVariable("keyword") String keyword) throws IOException {
return contentService.parseContent(keyword);
}
@GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
public List<Map<String, Object>> searchPage(@PathVariable("keyword") String keyword,
@PathVariable(value = "pageNo") Integer pageNo,
@PathVariable("pageSize") Integer pageSize)
throws IOException {
return contentService.searchPage(keyword, pageNo, pageSize);
}
}
简单写一个网页 通过以下路径访问
代码语言:javascript复制@Controller
public class IndexController {
@GetMapping("/")
public String index(){
return "index";
}
}
效果如下
(可以清楚的看到搜索的java关键字高亮)
源码如下
Aaron-ES-JD