SpringBoot 整合ElasticSearch基础
持续更新…
入门工程
大致工程结构图:
引入主要依赖:
<!-- Json处理依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<!-- ES依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
新建配置类:
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<String,Object> 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<Book> 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("<h1 style='color:red'>"); // 设置高亮前缀
highlightBuilder.postTags("</h1>"); // 设置高亮后缀
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<String> result = new ArrayList<>();
for(SearchHit hit:hits){
Map<String, HighlightField> 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<String, Object> 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<Book> 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的文档
条件查询
入门实战
测试结果
最终效果显示(这个是临时手搓的,页面很丑,主要还是看功能… )
以上基本实现了关键字标红…
构建后端
大致结构:
引入主要依赖
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<!-- 解析网页依赖 -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.10.2</version>
</dependency>
<!-- Json处理 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
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;
}
/**
* 从startId开始连续批处理添加文档
* @param indexName
* @param startId
* @param keyword
* @return
*/
public Boolean addBooks(String indexName,String startId,String keyword) {
try {
ArrayList<Book> 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;
}
}
/**
* 根据关键字分页查询,并且高亮显示
* @param indexName
* @param fieldName
* @param keyword
* @param offset
* @param size
* @return
*/
public ArrayList<Map<String,Object>> searchBooks(String indexName,String fieldName,String keyword,int offset,int size){
SearchRequest searchRequest = new SearchRequest(indexName);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(fieldName,keyword); // 模糊构建
HighlightBuilder highlightBuilder = new HighlightBuilder(); // 高亮构建
highlightBuilder.field(fieldName);
highlightBuilder.preTags("<span style='color:red' >");
highlightBuilder.postTags("</span>");
highlightBuilder.requireFieldMatch(true); // 同一字段值下所有的匹配所有
// 高亮配置
searchSourceBuilder.highlighter(highlightBuilder);
// 条件匹配配置
searchSourceBuilder.query(matchQueryBuilder);
// 超时配置
searchSourceBuilder.timeout(TimeValue.timeValueSeconds(4));
// 分页配置
searchSourceBuilder.from(offset);
searchSourceBuilder.size(size);
// 执行请求
searchRequest.source(searchSourceBuilder);
try {
SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);
ArrayList<Map<String,Object>> result = new ArrayList<>();
for(SearchHit searchHit : searchResponse.getHits().getHits()){
// Map<String, Object> fields = searchHit.getSourceAsMap();
// result.add(fields);
Map<String, HighlightField> highlightFieldMap = searchHit.getHighlightFields();
HighlightField highlightField = highlightFieldMap.get(fieldName);
Map<String, Object> fields = searchHit.getSourceAsMap();
if(highlightField != null){
Text[] fragments = highlightField.fragments();
String temp = "";
for(Text text:fragments ){
temp += text;
}
fields.put(fieldName,temp); // 替换
result.add(fields);
}
}
return result;
} catch (IOException e) {
return null;
}
}
}
爬虫工具类(爬取京东书籍信息)
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<Book> books = getBooks(baseUrl,keyword);
// System.out.println(books.toString());
// }
public ArrayList<Book> getBooks(String keyword) throws IOException{
String url = "https://search.jd.com/Search?keyword="+keyword;
ArrayList<Book> 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<Map<String,Object>> 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
<template>
<div id="nav">
<router-link to="/"></router-link>
</div>
<router-view/>
</template>
<style>
</style>
router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
Home.vue
<template>
<div class="home">
<div class="head">
</div>
<div class="search-box">
<input type="text" v-model="keyword" placeholder="关键词">
<input type="text" v-model.number="offset" placeholder="起始页">
<input type="text" v-model.number="size" placeholder="页面大小">
<input type="button" value="搜索" class="search-btn" @click="searchKeyword">
</div>
<div class="box">
<div class="card" v-for="book in books">
<img class="book-img" :src="book.bookUrl" alt="">
<span class='book-name' v-html="book.bookName"></span>
<span class="book-price">{{book.bookPrice}}</span>
</div>
</div>
</div>
</template>
<script>
import axios from "axios"
export default {
name: 'Home',
data(){
return {
keyword : "",
offset: 0,
size: 10,
books: null
}
},
methods : {
searchKeyword:function () {
// @GetMapping("/search/{indexName}/{fieldName}/{keyword}/{offset}/{size}")
axios({
url: "/api/search/books/bookName/"+this.keyword+"/"+this.offset+"/"+this.size,
method: "get"
}).then(res => {
this.books = res.data;
}).catch(err => {
console.log(err);
})
}
}
}
</script>
<style scoped>
* {
padding: 0;
margin: 0;
}
.home {
background: rgba(200,200,200,0.2);
}
.head {
height: 70px;
width: auto;
background: rgb(51, 51, 51);
margin-bottom: 10px;
position: sticky;
top: 0px;
z-index: 1;
}
.search-box {
position: center;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 10px;
}
.search-box input {
width: 250px;
height: 20px;
border-radius: 10px 10px 10px 10px;
margin: 0 0 10px 0;
border-color: rgba(0, 161, 214,1);
border-width: 3px 3px 3px 3px;
box-shadow: 0 0 10px 10px rgba(111,111,111,0.3);
position: center;
}
.search-box .search-btn {
width: 100px;
height: 35px;
background: rgba(231, 231, 231,1);
}
.search-box .search-btn:hover {
color: rgba(0, 161, 214,1);
}
.box {
display: flex;
flex-wrap: wrap;
}
.box .card {
width: 260px;
height: 320px;
background: rgba(200,200,200,0.2);
padding: 20px;
margin: 10px;
text-align: center;
transition-duration: 0.5s;
}
.box .card:hover{
box-shadow: 0 0 20px 7px rgba(0, 0, 0, 0.3);
transform: scale(1.04,1.04);
}
.box .card .book-price {
display: block;
margin: 5px 0 0 0;
color: #09f;
}
.box .book-name {
font-size: 13px;
display: block;
font-weight: 400;
margin: 7px 0 0 0;
}
</style>
测试流程
- 首先通过API(http://localhost:8888/add/bulk/books)来爬取京东相应关键字图书数据,并批量存入ES中
- 前端页面输入相应参数(查询关键字,查询起始数据索引,查询数据条数)即可