SpringBoot 整合ElasticSearch基础

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中
  • 前端页面输入相应参数(查询关键字,查询起始数据索引,查询数据条数)即可
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值