- SpringBoot和es相关操作
- es集成SpringBoot
- 使用springboot操作es API
- 索引相关
- 文档相关
- ES实战
- 数据准备,静态页面解析
- 项目搭建,代码实现
上一篇学习 笔记: ElasticSearch核心概念与REST风格说明 SpringBoot和es相关操作 es集成SpringBoot
查看官方文档
1、es客户端
2、es客户端的类别和版本,使用7.14版本,因为这里使用的 是java高级客户端,但是7.15不推荐java高级客户端,使用的是客户端
3、使用Java REST Client [7.14]的Java High Level REST Client
4、根据官方文档学习
- 找到Java High Level REST Client 原生依赖
org.elasticsearch.client elasticsearch-rest-high-level-client 7.14.2
- 找对象 RestHighLevelClient
5、开始集成springboot
- 创建一个空项目
- 空项目建立完成之后,在这个空项目上增加一个springboot模块,并添加依赖,并为项目配置jdk1.8
- 检查项目的jdk和js(确保 jdk一定在 1.8以上)
- 检查项目导入的 es版本要和本地es版本一致,我本地用的是7.6.1
- 编写es配置类,绑定本地而是客户端,并且将RestHighLevelClient注入到spring容器中,让容器接管,到这一步,springboot和es集成已经完成,接下来可以通过高级客户端进行操作操作了
package com.wangjiale.springboot_es_api.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 ElasticsearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
return client;
}
}
本地 是127.0.0.1:9200
1、创建索引
package com.wangjiale.springboot_es_api;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
@SpringBootTest
class SpringbootEsApiApplicationTests {
@Autowired
public RestHighLevelClient restHighLevelClient;
//测试索引请求request
@Test
public void test1() throws IOException {
//创建索引请求
CreateIndexRequest indexRequest = new CreateIndexRequest("wangjiale_index");
//创建索引客户端
IndicesClient indices = restHighLevelClient.indices();
//索引客户端执行索引请求 IndicesClient
CreateIndexResponse indexResponse = indices.create(indexRequest,
RequestOptions.DEFAULT);//RequestOptions.DEFAULT 默认请求参数
System.out.println(indexResponse);
}
}
2、获得索引,判断索引是否存在
@Test
void test2() throws IOException{
//获取索引请求
GetIndexRequest index = new GetIndexRequest("wangjiale_index");
//通过高级客户端创建索引客户端
IndicesClient indices = restHighLevelClient.indices();
//索引客户端发出索引是否存在
boolean exists = indices.exists(index, RequestOptions.DEFAULT);
System.out.println(exists);
}
3、删除索引
@Test
public void test3() throws IOException {
//创建删除索引的请求
DeleteIndexRequest index = new DeleteIndexRequest("wangjiale_index");
//通过高级客户端创建索引客户端
IndicesClient indices = restHighLevelClient.indices();
//索引客端端 删除索引 AcknowledgedResponse 确认响应
AcknowledgedResponse delete = indices.delete(index, RequestOptions.DEFAULT);
//输出是否删除
System.out.println(delete.isAcknowledged());
}
使用文档时需要在有索引的基础上,在此之间建立索引“wangjiale_index”
1、创建测试文档;
// 创建文档 规则 put /wangjiale_index/_doc/doc_1
@Test
public void test4() throws IOException {
//获得索引
IndexRequest index = new IndexRequest("wangjiale_index");
User user1 = new User().setName("王五")
.setPassword("123456")
.setSex('男')
.setAge(3);
//设置文档id,也相当于是文档的标识 , index.id()如果不写参数就会默认生成
index.id("doc_1");
//设置请求时间
index.timeout(Timevalue.timevalueDays(1));
// 将我们的数据放入请求 json
index.source(JSON.toJSONString(user1), XContentType.JSON);
// 客户端发送请求,获取响应结果
IndexResponse indexResponse = restHighLevelClient.index(index, RequestOptions.DEFAULT);
System.out.println(indexResponse.toString());
System.out.println(indexResponse.status());
}
2、判断文档是否存在,存在 的话不打印_source信息
// 获取文档,判断是否存在 get /wangjiale_index/_doc/doc_1
@Test
public void test5() throws IOException {
//获得get请求 获取索引wangjiale_index 中doc_1 的内容
GetRequest getRequest = new GetRequest("wangjiale_index", "doc_1");
//这里不打印_source中的内容 ,因为这里主要判断文档是否存在
getRequest.fetchSourceContext(new FetchSourceContext(false));
getRequest.storedFields("_none_");
//判断该文档是否存在
boolean exists = restHighLevelClient.exists(getRequest, RequestOptions.DEFAULT);
System.out.println(exists);
}
3、获取文档信息
// 获取文档信息 get wangjiale_index/_doc/doc_1
@Test
public void test6() throws IOException {
//使用get 获取索引wangjiale_index 中doc_1 的内容
GetRequest getRequest = new GetRequest("wangjiale_index", "doc_1");
//发送get请求
GetResponse documentFields = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
System.out.println(documentFields);//相当于documentFields.toString()
System.out.println(documentFields.toString());
// 返回的全部内容和命令是一样的
}
4、更新文档
//更新文档
@Test
public void test7() throws IOException {
//创建更新请求
UpdateRequest updateRequest = new UpdateRequest("wangjiale_index", "doc_1");
//设置更新超时时间
updateRequest.timeout("1s");
//数据更新
User user1 = new User().setName("王五更新")
.setAge(13);
//更新请求文档
updateRequest.doc(JSON.toJSONString(user1), XContentType.JSON);
//高级客户端发送更新请求
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
//更新状态是否成功
System.out.println(updateResponse.status());
}
5、删除文档
// 删除文档记录
@Test
public void test8() throws IOException {
DeleteRequest deleteRequest = new DeleteRequest("wangjiale_index", "doc_1");
DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
System.out.println(delete.status());
}
6、批量插入
@Test
public void test9() throws IOException {
//设置批量请求
BulkRequest bulkRequest = new BulkRequest();
//设置时间
bulkRequest.timeout("10s");
ArrayList users = new ArrayList<>();
users.add(new User().setName("张三1")
.setPassword("123456")
.setSex('男')
.setAge(3));
users.add(new User().setName("张三2")
.setPassword("123456")
.setSex('女')
.setAge(13));
users.add(new User().setName("李四")
.setPassword("123456")
.setSex('男')
.setAge(39));
users.add(new User().setName("王五")
.setPassword("123456")
.setSex('男')
.setAge(74));
for (int i = 0; i < users.size(); i++) {
//批量增加
bulkRequest.add(new IndexRequest("wangjiale_index")//索引请求
.id("doc_"+(i+1))//文档id
.source(JSON.toJSONString(users.get(i)),XContentType.JSON));//文档数据
}
BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);//客户端发送批量请求
System.out.println(bulkResponse.hasFailures());//判断是否批量请求是否失败
}
7、批量更新
@Test
public void test9() throws IOException {
//设置批量请求
BulkRequest bulkRequest = new BulkRequest();
//设置时间
bulkRequest.timeout("10s");
ArrayList users = new ArrayList<>();
users.add(new User().setName("张三1更新")
.setPassword("123456")
.setSex('男')
.setAge(3));
users.add(new User().setName("张三e更新")
.setPassword("123456")
.setSex('女')
.setAge(13));
users.add(new User().setName("李四更新")
.setPassword("123456")
.setSex('男')
.setAge(39));
users.add(new User().setName("王五更新")
.setPassword("123456")
.setSex('男')
.setAge(74));
for (int i = 0; i < users.size(); i++) {
bulkRequest.add(new UpdateRequest("wangjiale_index", "doc_"+(i+1))
.doc(JSON.toJSONString(users.get(i)),XContentType.JSON));
}
BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);//客户端发送批量请求
System.out.println(bulkResponse.hasFailures());//判断是否批量请求是否失败
}
8、批量删除
@Test
public void test9() throws IOException {
//设置批量请求
BulkRequest bulkRequest = new BulkRequest();
//设置时间
bulkRequest.timeout("10s");
for (int i = 0; i < 4; i++) {
bulkRequest.add(new DeleteRequest("wangjiale_index", "doc_"+(i+1)));
}
BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);//客户端发送批量请求
System.out.println(bulkResponse.hasFailures());//判断是否批量请求是否失败
}
9、复杂搜索
数据准备
// 查询
// SearchRequest 搜索请求
// SearchSourceBuilder 条件构造
// HighLightBuilder 构建高亮
// TermQueryBuilder 精确查询
// MatchAllQueryBuilder
// xxx QueryBuilder 对应我们刚才看到的命令!
@Test
public void test10() throws IOException {
//创建搜索请求
SearchRequest searchRequest = new SearchRequest("wangjiale_index");
//构建搜索条件 SearchSourceBuilder 我们要的数据都在_source中
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
//创建查询条件,我们使用工具类QueryBuilders
//bool查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//“or”查询
boolQuery.should(QueryBuilders.matchQuery("name","张三"));
boolQuery.should(QueryBuilders.matchQuery("age",74));
//分页
sourceBuilder.from(0);
sourceBuilder.size(10);
//将查询条件放入搜索构建器中
sourceBuilder.query(boolQuery);
//设置查询时间
sourceBuilder.timeout(new Timevalue(60));
//把搜索构建器放入搜索请求中
SearchRequest source = searchRequest.source(sourceBuilder);
SearchResponse search = restHighLevelClient.search(source, RequestOptions.DEFAULT);
SearchHits hits = search.getHits();
SearchHit[] hits1 = hits.getHits();
for (SearchHit documentFields : hits1) {
System.out.println(documentFields);
} }
结果
{
"_index" : "wangjiale_index",
"_type" : "_doc",
"_id" : "doc_2",
"_score" : 1.4523083,
"_source" : {
"age" : 13,
"name" : "张三",
"password" : "123456",
"sex" : "女"
}
}
{
"_index" : "wangjiale_index",
"_type" : "_doc",
"_id" : "doc_1",
"_score" : 1.2199391,
"_source" : {
"age" : 3,
"name" : "张三1",
"password" : "123456",
"sex" : "男"
}
}
{
"_index" : "wangjiale_index",
"_type" : "_doc",
"_id" : "doc_4",
"_score" : 1.0,
"_source" : {
"age" : 74,
"name" : "王五",
"password" : "123456",
"sex" : "男"
}
}
ES实战
静态页面资源提取
链接:链接:https://pan.baidu.com/s/1NxOfgXPOs75Zcn51bc-YLw
提取码:nku8
1、创建项目,步骤如下
2、把准备的静态资源放入项目中
测试将静态资源放入项目中是否成功
数据问题?数据库获取,消息队列中获取,都可以成为数据源,爬虫!
爬取数据:(获取请求返回的页面信息,筛选出我们想要的数据就可以了!)
导入jsoup包
org.jsoup jsoup 1.13.1
编写工具包,并测试 是否可以拿到京东静态页面数据
public static void main(String[] args) throws Exception {
//获取请求 keyword参数是关键字搜索
String url ="https://search.jd.com/Search?keyword=nars";
//使用Jsoup.parse 解析请求,第一个参数是url请求,第二个参数是超时时间
// 解析网页。(Jsoup 返回document就是document对象)
document parse = Jsoup.parse(new URL(url), 300000);
//此时已经获得请求返回也页面的document对象
//通过document对象获取div(J_goodsList),搜索商品列表
Element j_goodsList = parse.getElementById("J_goodsList");
//获得div中的所有列表
Elements lis = j_goodsList.getElementsByTag("li");
//遍历列表,并取出里面的数据
for (Element li : lis) {
// 因为京东是延时加载 所以要加载图片是data-lazy-img
String img = li.getElementsByTag("img").eq(0).attr("data-lazy-img");// 获取li下第一张图片
//获得价格div
String price = li.getElementsByClass("p-price").eq(0).text();
//获得名字div
String name = li.getElementsByClass("p-name").eq(0).text();
System.out.println("图片:"+img);
System.out.println("价格:"+price);
System.out.println("name:"+name);
}
}
把工具包封装成一个方法
public class HtmlParseUtil {
public static List parseJD(String keywords) throws Exception {
List list = new ArrayList<>();
String url ="https://search.jd.com/Search?keyword="+keywords;
document parse = Jsoup.parse(new URL(url), 300000);
Element j_goodsList = parse.getElementById("J_goodsList");
Elements lis = j_goodsList.getElementsByTag("li");
for (Element li : lis) {
// 因为京东是延时加载 所以要加载图片是data-lazy-img
String img = li.getElementsByTag("img").eq(0).attr("data-lazy-img");// 获取li下第一张图片
//获得价格div
String price = li.getElementsByClass("p-price").eq(0).text();
//获得名字div
String name = li.getElementsByClass("p-name").eq(0).text();
Jd_Content jd_content = new Jd_Content();
jd_content.setImg(img).setPrice(price).setName(name);
list.add(jd_content);
}
return list;
}
}
项目搭建,代码实现
此时项目结构如下图
项目中所有的依赖
4.0.0 org.springframework.boot spring-boot-starter-parent 2.5.5 com.wangjiale jd-springboot-es 0.0.1-SNAPSHOT jd-springboot-es Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-data-elasticsearch org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-devtools runtime true org.springframework.boot spring-boot-configuration-processor true org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.jsoup jsoup 1.13.1 com.alibaba fastjson 1.2.47 org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok
实体类:
1、Indexes (es中的索引名字)
package com.wangjiale.jd_springboot_es.entity;
public class Indexes {
public static String NAME ="jd_index";
}
2、Jd_Content (京东商品信息)
package com.wangjiale.jd_springboot_es.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Jd_Content {
private String img;
private String price;
private String name;
}
配置文件:
package com.wangjiale.jd_springboot_es.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 ElasticsearchConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("127.0.0.1", 9200, "http")));
return client;
}
}
业务逻辑:
1、EsService
package com.wangjiale.jd_springboot_es.service;
import com.wangjiale.jd_springboot_es.entity.Jd_Content;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public interface EsService {
public Boolean parseContent(String keywords) throws Exception;
public List
2、EsServiceImp
package com.wangjiale.jd_springboot_es.service.impl;
import com.alibaba.fastjson.JSON;
import com.wangjiale.jd_springboot_es.entity.Indexes;
import com.wangjiale.jd_springboot_es.entity.Jd_Content;
import com.wangjiale.jd_springboot_es.service.EsService;
import com.wangjiale.jd_springboot_es.util.HtmlParseUtil;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Timevalue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
public class EsServiceImp implements EsService {
@Autowired
RestHighLevelClient restHighLevelClient;
public Boolean parseContent(String keywords) throws Exception {
List jd_contents = HtmlParseUtil.parseJD(keywords);
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("2m");
for (Jd_Content jd_content : jd_contents) {
bulkRequest.add(
new IndexRequest(Indexes.NAME).
source(JSON.toJSONString(jd_content),XContentType.JSON));
}
BulkResponse bulk = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
return !bulk.hasFailures();
}
@Override
public List
控制器:
package com.wangjiale.jd_springboot_es.controller;
import com.wangjiale.jd_springboot_es.entity.Jd_Content;
import com.wangjiale.jd_springboot_es.service.EsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@RestController
public class EsController {
@Autowired
public EsService esService;
@GetMapping("/parse/{keysword}")
public Boolean parse(@PathVariable("keysword") String keysword) throws Exception {
return esService.parseContent(keysword);
}
@GetMapping("/search/{keywords}/{pageNo}/{pageSize}")
public List> search(@PathVariable("keywords") String keywords,
@PathVariable("pageNo")int pageNo,
@PathVariable("pageSize")int pageSize) throws IOException {
List> secher = esService.secher(keywords, pageNo, pageSize);
return secher;
}
}
页面显示 :使用Vue做前后端分离
王家乐-仿京东实战
启动类:
package com.wangjiale.jd_springboot_es;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class JdSpringbootEsApplication {
public static void main(String[] args) {
SpringApplication.run(JdSpringbootEsApplication.class, args);
}
}
最终效果图:



