集成 SpringBoot
找官方文档!
选择Rest接口风格的客户端
我们一般选用高级客户端
1、找到原生的依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.6.2</version>
</dependency>
2、找对象
3、分析这个类中的方法即可!
配置基本的项目
项目创建
- 先创建一个Maven空项目
- 然后在空项目中创建一个springboot模块
勾选开发所需要的包
创建项目成功后,修改我们相应的ES版本
<properties>
<java.version>1.8</java.version>
<!--自定义es版本以来,和本地一致-->
<elasticsearch.version>7.13.2</elasticsearch.version>
</properties>
查看idea中maven依赖是否修改成功
编写ES的Config配置文件
ElasticSearchClientConfig
package com.sz.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
具体的 Api 测试!
1、创建索引
// 测试索引的创建 Request PUT kuang_index
@Test
void testCreateIndex() throws IOException {
// 1、创建索引请求
CreateIndexRequest request = new CreateIndexRequest("leosu_index");
// 2、客户端执行请求 IndicesClient,请求后获得响应
CreateIndexResponse createIndexResponse =
client.indices().create(request, RequestOptions.DEFAULT);
System.out.println(createIndexResponse);
}
2、判断索引是否存在
//测试获取索引
@Test
void testExistIndex() throws IOException{
GetIndexRequest request = new GetIndexRequest("leosu_index");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
3、删除索引
// 测试删除索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("leosu_index");
//删除
AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
System.out.println(delete.isAcknowledged());
}
4、创建文档
首先创建User实体类
package com.huang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class User {
private String name;
private int age;
}
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
//测试添加文档
@Test
void testAddDocument() throws IOException {
//创建对象
User user = new User("狂神说", 3);
//创建请求
IndexRequest request = new IndexRequest("leosu_index");
//规则 put /leosu_index/_doc/1
request.id("1");
request.timeout(TimeValue.timeValueSeconds(1));
request.timeout("1s");
// 将我们的数据放入请求 json
request.source(JSON.toJSONString(user), XContentType.JSON);
// 客户端发送请求 , 获取响应的结果
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());//数据
System.out.println(indexResponse.status());// 对应我们命令返回的状态CREATED
}
5、判断文档是否存在
// 获取文档,判断是否存在 get /index/doc/1
@Test
void testIsExists() throws IOException {
GetRequest getRequest = new GetRequest("leosu_index", "1");
// 不获取返回的 _source 的上下文了
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
boolean exists = client.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
6、获取文档信息
// 获得文档的信息
@Test
void testGetDocument() throws IOException {
GetRequest getRequest = new GetRequest("leosu_index", "1");
GetResponse getResponse = client.get(getRequest,RequestOptions.DEFAULT);
System.out.println(getResponse.getSourceAsString()); // 打印文档的内容
System.out.println(getResponse); // 返回的全部内容和命令式一样的
}
7、更新文档的信息
// 更新文档的信息
@Test
void testUpdateRequest() throws IOException {
UpdateRequest request = new UpdateRequest("leosu_index","1");
request.timeout("1s");
User user = new User("张三", 18);
request.doc(JSON.toJSONString(user),XContentType.JSON);
UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
System.out.println(update.status());
}
8、删除文档记录
// 删除文档记录
@Test
void testDeleteRequest() throws IOException {
DeleteRequest request = new DeleteRequest("leosu_index","1");
request.timeout("1s");
DeleteResponse deleteResponse = client.delete(request,
RequestOptions.DEFAULT);
System.out.println(deleteResponse.status());
}
9、特殊的,真的项目一般都会批量插入数据!
// 特殊的,真的项目一般都会批量插入数据!
@Test
void testBulkRequest() throws IOException {
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("10s");
List<User> userList = new ArrayList<>();
userList.add(new User("花木兰",20));
userList.add(new User("凯",21));
userList.add(new User("百里玄策",22));
userList.add(new User("百里守约",23));
userList.add(new User("苏烈",24));
//批量处理数据
for (int i = 0; i < userList.size(); i++) {
//批量删除和修改就在这里操作
bulkRequest.add(
new IndexRequest("kuang_index")
.id(""+(i+1))
.source(JSON.toJSONString(userList.get(i)),XContentType.JSON)
);
}
BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
System.out.println(bulk.hasFailures());//是否执行失败
}
10、查询
// 查询
// SearchRequest 搜索请求
// SearchSourceBuilder 条件构造
// HighlightBuilder 构建高亮
// TermQueryBuilder 精确查询
// MatchAllQueryBuilder
// xxx QueryBuilder 对应我们刚才看到的命令!
@Test
void testSearch() throws IOException {
SearchRequest searchRequest = new SearchRequest("leosu_index");
//构建搜索条件
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//查询条件,我们可以使用SearchSourceBuilder工具来实现
//精确匹配QueryBuilders.termQuery()
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "kuangshen1");
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
System.out.println(JSON.toJSONString(searchResponse));
System.out.println("+++++++++++++++++++++++++++++++++++++++++");
for (SearchHit hit : searchResponse.getHits()) {
System.out.println(hit.getSourceAsMap());
}
}
实战
仿京东搜索项目准备工作
新建一个项目
pom版本与前面集成springboot的版本相同!
配置application.properties
server.port=9090
#关闭thymeleaf的缓存
spring.thymeleaf.cache=false
获取前端页面资料
编写IndexController
package com.sz.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@RequestMapping({"/","/index"})
public String index(){
return "index";
}
}
启动测试
爬虫
数据问题?数据库获取,消息队列中获取中,都可以成为数据源,爬虫!
导入依赖解析网页
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.2</version>
</dependency>
爬取数据:(获取请求返回的页面信息,筛选出我们想要的数据就可以了!)
前后端分离(含搜索高亮)
Vue下载
-
随便创建一个文件夹
-
文件夹下启动
cmd
命令 -
执行命令
npm install vue
- 然后执行
npm install axios
所以将下载的vue和axios里的dist文件中的js文件放入项目里
核心代码编写
config
ElasticSearchClientConfig
//狂神Spring两步骤
//1.找对象
//2.放到Spring中待用
//3.如果是SpringBoot就分析一波源码
//XXXAutoConfiguration XXXProperties
@Configuration
public class ElasticSearchClientConfig {
@Bean
public RestHighLevelClient restHighLevelClient() {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("localhost", 9200, "http")));
return client;
}
}
pojo
Content
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content {
private String img;
private String price;
private String title;
private String commit;
private String shopnum;
}
HtmlParseUtil
爬虫工具类HtmlParseUtil
@Component
public class HtmlParseUtil {
public List<Content> parseJD(String keywords) throws IOException {
//获取请求: https://search.jd.com/Search?keyword=java&enc=utf-8&wq=java&pvid=f807c58b66dc4baab4c7ed71834c36be
//前提,联网,ajax不能获得
String url = "https://search.jd.com/Search?keyword="+keywords+"&enc=utf-8";
//解析网页。(JIsoup返 回Document就是浏览器Document对象)
Document document = Jsoup.parse(new URL(url), 30000);
//所有你在js中可以使用的方法,这里都能用!
Element element = document.getElementById("J_goodsList");
//System.out.println(element.html());
//获取所有的Li元素
Elements elements = element.getElementsByTag("li");
//
List<Content> contents = new ArrayList<>();
//获取元素中的内容,这也就是每一 个Li标签了!
for (Element el : elements) {
//由于图片是延迟加载
//data-lazy-img
String img = el.getElementsByTag("img").eq(0).attr("data-lazy-img");
String price = el.getElementsByClass("p-price").eq(0).text();
String title = el.getElementsByClass("p-name").eq(0).text();
String commit = el.getElementsByClass("p-commit").eq(0).text();
String shopnum = el.getElementsByClass("p-shopnum").eq(0).text();
contents.add(new Content(img,price,title,commit,shopnum));
}
return contents;
}
}
controller
IndexController
@Controller
public class IndexController {
@RequestMapping({"/","/index"})
public String index(){
return "index";
}
}
ContentController
//请求编写
@RestController//只返回数据
public class ContentController {
@Autowired
private ContentService contentService;
@GetMapping("/parse/{keyword}")
public Boolean parse(@PathVariable("keyword") String keyword) throws Exception {
return contentService.parseContent(keyword);
}
@GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
public List<Map<String, Object>> search(@PathVariable("keyword") String keyword,
@PathVariable("pageNo") int pageNo,
@PathVariable("pageSize") int pageSize) throws IOException {
//return contentService.searchPage(keyword, pageNo, pageSize);searchPageHighlightBuilder
return contentService.searchPageHighlightBuilder(keyword, pageNo, pageSize);
}
}
service
ContentService
//业务编写
@Service
public class ContentService {
@Autowired
private RestHighLevelClient restHighLevelClient;
// 1.解析数据放入 es索引中
public Boolean parseContent(String keywords) throws Exception {
List<Content> contents = new HtmlParseUtil().parseJD(keywords);
/*// 1、创建索引请求
CreateIndexRequest request = new CreateIndexRequest("jd_goods");
// 2、客户端执行请求 IndicesClient,请求后获得响应
System.out.println("创建开始");
restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
System.out.println("创建成功");*/
//把查询到的数据放入es中
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("2m");
for (int i = 0; i < contents.size(); i++) {
bulkRequest.add(
new IndexRequest("jd_goods")
.source(JSON.toJSONString(contents.get(i)), XContentType.JSON));
}
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
return !bulk.hasFailures();
}
// 2.获取这些数据实现搜索功能
public List<Map<String, Object>> searchPage(String keyword, int pageNo, int pageSize) throws IOException {
if (pageNo <= 1) {
pageNo = 1;
}
//条件搜索
SearchRequest searchRequest = new SearchRequest("jd_goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//分页
sourceBuilder.from(pageNo);
sourceBuilder.size(pageSize);
//精准匹配
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", keyword);
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//执行搜索
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>();
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
list.add(documentFields.getSourceAsMap());
}
return list;
}
// 2.获取这些数据实现搜索高亮功能
public List<Map<String, Object>> searchPageHighlightBuilder(String keyword, int pageNo, int pageSize) throws IOException {
if (pageNo <= 1) {
pageNo = 1;
}
//条件搜索
SearchRequest searchRequest = new SearchRequest("jd_goods");
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//分页
sourceBuilder.from(pageNo);
sourceBuilder.size(pageSize);
//精准匹配
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", keyword);
sourceBuilder.query(termQueryBuilder);
sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("title");
highlightBuilder.requireFieldMatch(false); //多个高亮显示
highlightBuilder.preTags("<span style='color:red'>");
highlightBuilder.postTags("</span>");
sourceBuilder.highlighter(highlightBuilder);
//执行搜索
searchRequest.source(sourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>();
for (SearchHit hit : searchResponse.getHits().getHits()) {
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
HighlightField title = highlightFields.get("title");
Map<String, Object> sourceAsMap = hit.getSourceAsMap(); //原来的结果!
//解析高亮的字段,将原来的字段换为我们高亮的字段即可!
if (title != null) {
Text[] fragments = title.fragments();
String n_title = "";
for (Text text : fragments) {
n_title += text;
sourceAsMap.put("title", n_title); //高亮字段替换掉原来的内容即可!
}
list.add(sourceAsMap);
}
}
return list;
}
}
代码资料
全部代码已上传至码云
评论区