
SpringBoot 整合ElasticSearch基础
持续更新…
入门工程建议读者先学习这儿的前置知识…
大致工程结构图:
引入主要依赖:
com.alibaba fastjson1.2.71 org.springframework.boot spring-boot-starter-data-elasticsearchorg.springframework.boot spring-boot-starter-weborg.projectlombok lomboktrue
新建配置类:
package cn.wu.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 ESConfig {
@Bean
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder( // 构建连接对象
new HttpHost("127.0.0.1",9200,"http")));
return restHighLevelClient;
}
}
新建业务层:
package cn.wu.service;
import cn.wu.pojo.Book;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Timevalue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service("esServiceBean")
public class ESService {
private RestHighLevelClient restHighLevelClient;
@Autowired
@Qualifier("restHighLevelClient")
public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
this.restHighLevelClient = restHighLevelClient;
}
// 创建索引
public Boolean createIndex(String indexName){
try{
// 1.创建索引 *** 作对象请求
CreateIndexRequest indexRequest = new CreateIndexRequest(indexName);
// 2.客户端执行请求
CreateIndexResponse createIndexResponse = restHighLevelClient.indices()
.create(indexRequest, RequestOptions.DEFAULT);
return true;
}catch (IOException e){
return false;
}
}
// 判断索引是否存在
public Boolean existIndex(String indexName){
// 1.创建索引 *** 作对象请求
GetIndexRequest indexRequest = new GetIndexRequest(indexName);
// 2.客户端执行请求判断索引是否存在
Boolean flag = false;
try{
flag = restHighLevelClient.indices().exists(indexRequest,RequestOptions.DEFAULT);
}catch(IOException e){}
return flag;
}
// 删除索引
public Boolean deleteIndex(String indexName){
// 1.创建索引 *** 作对象请求
DeleteIndexRequest indexRequest = new DeleteIndexRequest(indexName);
// 2.客户端执行请求删除索引
Boolean flag = false;
AcknowledgedResponse acknowledgedResponse = null;
try{
acknowledgedResponse = restHighLevelClient.indices().delete(indexRequest, RequestOptions.DEFAULT);
}catch(IOException e){}
if(acknowledgedResponse != null){
flag = acknowledgedResponse.isAcknowledged(); // 获取状态
}
return flag;
}
// 添加对应ID的文档(Book)
public Boolean addBook(String indexName,String id,Book book){
// 1.创建索引 *** 作对象请求
IndexRequest indexRequest = new IndexRequest(indexName);
// 2.配置规则属性
indexRequest.id(id);
indexRequest.timeout("1s"); // 过期时间设置
// 3.返回的数据转化为Json
indexRequest.source(JSON.toJSONString(book), XContentType.JSON);
// 4.客户端发送请求
try{
IndexResponse indexResponse = restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);
log.info("响应对象为: "+indexResponse.toString());
log.info("响应状态为: "+indexResponse.status().toString());
return true;
}catch(IOException e){
return false;
}
}
// 判断文档(Book)是否存在
public Boolean existBook(String indexName,String id){
// 1.创建索引 *** 作对象请求
GetRequest getRequest = new GetRequest(indexName,id);
// 2.客户端发送请求
try{
return restHighLevelClient.exists(getRequest,RequestOptions.DEFAULT);
}catch(IOException e){
return false;
}
}
// 获取文档(Book)_source信息
public Map getBook(String indexName, String id){
// 1.创建索引 *** 作对象请求
GetRequest getRequest = new GetRequest(indexName,id);
// 2.客户端发送请求
GetResponse getResponse = null;
try{
getResponse = restHighLevelClient.get(getRequest,RequestOptions.DEFAULT);
return getResponse.getSource();
}catch(IOException e){
return null;
}
}
// 更新文档(Book)信息 局部修改方式
public Boolean updateBook(String indexName,String id,Book book){
// 1.创建索引 *** 作对象请求
UpdateRequest updateRequest = new UpdateRequest(indexName,id);
// 2.客户端发送请求
UpdateResponse updateResponse = null;
try{
updateRequest.doc(JSON.toJSONString(book),XContentType.JSON);
updateResponse = restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);
log.info("更新文档: "+updateResponse.status());
return true;
}catch(IOException e){
return false;
}
}
// 删除文档(Book)
public Boolean deleteBook(String indexName,String id){
// 1.创建索引 *** 作对象请求
DeleteRequest deleteRequest = new DeleteRequest(indexName,id);
deleteRequest.timeout("1s");
// 2.客户端发送请求
DeleteResponse deleteResponse = null;
try{
deleteResponse = restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);
log.info("删除文档: "+deleteResponse.status());
return true;
}catch(IOException e){
return false;
}
}
// 批量添加文档(Book) 从startId位置开始连续批量添加
public Boolean addBulkBook(String indexName, String startId, ArrayList books){
// 1.创建索引 *** 作对象请求
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("3s");
// 2.创建批处理请求
int offset = Integer.parseInt(startId);
for(int i = 0 ; i < books.size() ; i++){
// 同理,批处理修改
// UpdateRequest updateRequest = new UpdateRequest(indexName,startId);
// 同理,批处理删除
// DeleteRequest deleteRequest = new DeleteRequest(indexName,startId);
IndexRequest indexRequest = new IndexRequest(indexName);
indexRequest.id(offset+i+"");
indexRequest.source(JSON.toJSONString(books.get(i)),XContentType.JSON);
bulkRequest.add(indexRequest);
}
// 3.客户端发送请求
try{
BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
log.info("批量添加文档: "+bulkResponse.status());
return true;
}catch(IOException e){
return false;
}
}
// 条件查询(重要) 这里以模糊匹配并高亮为例
public Object searchBook(String indexName, String fieldName, String value){
// 1.构建搜索请求
SearchRequest searchRequest = new SearchRequest(indexName);
// 2.构建搜索条件
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 常用查询条件
// 2.1 QueryBuilders.termQuery() 精确
// TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(name,value);
// searchSourceBuilder.query(termQueryBuilder);
// 2.2 QueryBuilders.matchAllQuery() 查询全部
// 2.3 QueryBuilders.boolQuery() 高级条件查询
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(fieldName,value);
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field(fieldName); // 设置高亮字段
highlightBuilder.preTags(""); // 设置高亮前缀
highlightBuilder.postTags(""); // 设置高亮后缀
highlightBuilder.requireFieldMatch(true); // 多个字段均高亮
// 3.构造器绑定
searchSourceBuilder.query(matchQueryBuilder);
searchSourceBuilder.highlighter(highlightBuilder);
searchSourceBuilder.timeout(new Timevalue(5, TimeUnit.SECONDS)); // 超时时间
searchRequest.source(searchSourceBuilder);
// 4.客户端发送请求 获取高亮数据
try{
SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
ArrayList result = new ArrayList<>();
for(SearchHit hit:hits){
Map highlightFields = hit.getHighlightFields();
Text[] texts = highlightFields.get(fieldName).getFragments();
String str = "";
for(Text text:texts){
str += text;
}
result.add(str);
}
return result;
}catch(IOException e){
return null;
}
}
}
新建控制层:
package cn.wu.controller;
import cn.wu.pojo.Book;
import cn.wu.service.ESService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Map;
@RestController
public class ESController {
private ESService esService;
@Autowired
@Qualifier("esServiceBean")
public void setEsService(ESService esService) {
this.esService = esService;
}
@GetMapping("/create/index/{indexName}")
public Boolean createIndex(@PathVariable("indexName") String indexName){
return esService.createIndex(indexName);
}
@GetMapping("/exist/index/{indexName}")
public Boolean existIndex(@PathVariable("indexName") String indexName){
return esService.existIndex(indexName);
}
@GetMapping("/delete/index/{indexName}")
public Boolean deleteIndex(@PathVariable("indexName") String indexName){
return esService.deleteIndex(indexName);
}
@PostMapping("/add/{indexName}/{id}")
public Boolean addBook(@RequestBody Book book,
@PathVariable("indexName") String indexName,
@PathVariable("id") String id){
return esService.addBook(indexName,id,book);
}
@GetMapping("/exist/{indexName}/{id}")
public Boolean existBook(@PathVariable("indexName") String indexName,
@PathVariable("id") String id){
return esService.existBook(indexName,id);
}
@GetMapping("/get/{indexName}/{id}")
public Map getBook(@PathVariable("indexName") String indexName,
@PathVariable("id") String id){
return esService.getBook(indexName,id);
}
@PostMapping("/update/{indexName}/{id}")
public Boolean updateBook(@RequestBody Book book,
@PathVariable("indexName") String indexName,
@PathVariable("id") String id){
return esService.updateBook(indexName,id,book);
}
@GetMapping("/delete/{indexName}/{id}")
public Boolean deleteBook(@PathVariable("indexName") String indexName,
@PathVariable("id") String id){
return esService.deleteBook(indexName,id);
}
@PostMapping("/add/bulk/{indexName}/{startId}")
public Boolean addBulkBook(@PathVariable("indexName") String indexName,
@PathVariable("startId") String startId,
@RequestBody ArrayList books){
return esService.addBulkBook(indexName,startId,books);
}
@GetMapping("/search/{indexName}/{fieldName}/{value}")
public String searchBook(@PathVariable("indexName") String indexName,
@PathVariable("fieldName") String fieldName,
@PathVariable("value") String value){
return esService.searchBook(indexName,fieldName,value);
}
}
启动之前要先打开ES集群,测试结果:
首先新建book_index的索引
判断ES中是否存在book_index索引
删除book_index的索引
添加文档
判断相应ID的文档是否存在
获取相应ID的文档
修改相应ID的文档
删除相应ID的文档
批量连续添加特定起始ID的文档
条件查询
入门实战 测试结果最终效果显示(这个是临时手搓的,页面很丑,主要还是看功能… )
以上基本实现了关键字标红…
构建后端大致结构:
引入主要依赖
1.8 UTF-8 UTF-8 2.3.7.RELEASE org.jsoup jsoup1.10.2 com.alibaba fastjson1.2.71 org.springframework.boot spring-boot-starter-data-elasticsearchorg.springframework.boot spring-boot-starter-weborg.projectlombok lomboktrue org.springframework.boot spring-boot-dependencies${spring-boot.version} pom import
appilcation.yml
server: port: 8888
主启动类
package cn.wu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ESApplication {
public static void main(String[] args) {
SpringApplication.run(ESApplication.class,args);
}
}
ES配置类
package cn.wu.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 ESConfig {
@Bean("restHighLevelClient")
public RestHighLevelClient restHighLevelClient(){
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(
RestClient.builder( // 构建连接对象
new HttpHost("127.0.0.1",9200,"http")));
return restHighLevelClient;
}
}
实体类
package cn.wu.pojo;
import lombok.Data;
import lombok.Setter;
@Data
@Setter
public class Book {
private String bookName;
private String bookPrice;
private String bookUrl;
}
业务层
package cn.wu.service;
import cn.wu.pojo.Book;
import cn.wu.utils.HtmlUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
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.text.Text;
import org.elasticsearch.common.unit.Timevalue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
@Slf4j
@Service("bookServiceBean")
public class BookService {
private RestHighLevelClient restHighLevelClient;
@Autowired
@Qualifier("restHighLevelClient")
public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
this.restHighLevelClient = restHighLevelClient;
}
private HtmlUtil htmlUtil;
@Autowired
public void setHtmlUtil(HtmlUtil htmlUtil) {
this.htmlUtil = htmlUtil;
}
public Boolean addBooks(String indexName,String startId,String keyword) {
try {
ArrayList books = htmlUtil.getBooks(keyword);
BulkRequest bulkRequest = new BulkRequest();
bulkRequest.timeout("4s");
for(int i = 0 ; i < books.size() ; i++){
IndexRequest indexRequest = new IndexRequest(indexName);
indexRequest.id((startId+i)+"");
bulkRequest.add(indexRequest.source(JSON.toJSONString(books.get(i)), XContentType.JSON));
}
BulkResponse bulkResponse = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
log.info("批处理添加的状态为: "+bulkResponse.status());
return true;
} catch (IOException e) {
return false;
}
}
public ArrayList
爬虫工具类(爬取京东书籍信息)
package cn.wu.utils;
import cn.wu.pojo.Book;
import org.jsoup.Jsoup;
import org.jsoup.nodes.document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.ArrayList;
@Component
public class HtmlUtil {
// public static void main(String[] args) throws IOException {
// // 获取请求
// String baseUrl = "https://search.jd.com/Search?keyword=";
// String keyword = "SpringCloud";
//
// ArrayList books = getBooks(baseUrl,keyword);
// System.out.println(books.toString());
// }
public ArrayList getBooks(String keyword) throws IOException{
String url = "https://search.jd.com/Search?keyword="+keyword;
ArrayList result = new ArrayList<>();
document document = Jsoup.connect(url).get();
Element element = document.getElementById("J_goodsList");
Elements elements = element.getElementsByTag("li");
for(Element e:elements){
String img = e.getElementsByTag("img").eq(0).attr("data-lazy-img");
String price = e.getElementsByClass("p-price").eq(0).text();
String name = e.getElementsByClass("p-name").eq(0).text();
Book book = new Book();
book.setBookName(name);
book.setBookUrl(img);
book.setBookPrice(price);
result.add(book);
}
return result;
}
}
控制层
package cn.wu.pojo;
import lombok.Data;
import lombok.Setter;
@Data
@Setter
public class Book {
private String bookName;
private String bookPrice;
private String bookUrl;
}
控制层
package cn.wu.controller;
import cn.wu.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Map;
@RestController
public class BookController {
private BookService bookService;
@Autowired
@Qualifier("bookServiceBean")
public void setBookService(BookService bookService) {
this.bookService = bookService;
}
@GetMapping("/add/bulk/{indexName}/{startId}/{keyword}")
public Boolean addBulkBooks(@PathVariable("indexName") String indexName,
@PathVariable("startId") String startId,
@PathVariable("keyword") String keyword){
return bookService.addBooks(indexName, startId, keyword);
}
@GetMapping("/search/{indexName}/{fieldName}/{keyword}/{offset}/{size}")
public ArrayList> searchBooks(@PathVariable("indexName") String indexName,
@PathVariable("fieldName") String fieldName,
@PathVariable("keyword") String keyword,
@PathVariable("offset") Integer offset,
@PathVariable("size") Integer size){
return bookService.searchBooks(indexName,fieldName,keyword,offset,size);
}
}
构建前端
这儿读者需要事先安装node.js以及vue-cli,相关内容读者可以查看这里…
选择一个文件夹,执行vue create elasticsearch-vue,修改后的大致结构为:
vue.config.js(跨域问题解决)
module.exports = {
devServer:{
proxy:{
'/api':{ // 设置拦截器
target: 'http://localhost:8888', // 设置代理目标地址
changeOrigin: true, //是否设置同源
pathRewrite:{
'/api':'' // 代理之后将/api替换为空字符串
}
}
}
}
}
App.vue
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)