栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ElasticSearch集成SpringBoot+实战

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ElasticSearch集成SpringBoot+实战

ElasticSearch集成SpringBoot+搜索页面实战(仿京东)
  • 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

使用springboot操作es API 索引相关

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> secher(String keywords, int pageNo, int pageSize) throws IOException;
}

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> secher(String keywords, int pageNo, int pageSize) throws IOException {
        if (pageNo <=1){
            pageNo =1;
        }
        ArrayList> maps = new ArrayList<>();
        //创建搜索请求
        SearchRequest searchRequest = new SearchRequest(Indexes.NAME);
        //构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        sourceBuilder.query(new MatchQueryBuilder("name",keywords));

        sourceBuilder.timeout(new Timevalue(10000));

        //设置分页

        sourceBuilder.from(pageNo);
        sourceBuilder.size(pageSize);

        //把搜索条件放入搜索请求
        searchRequest.source(sourceBuilder);

        //执行搜索
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);

        SearchHits hits = searchResponse.getHits();

        for (SearchHit hit : hits) {
            maps.add(hit.getSourceAsMap());
        }
        return maps;


    }
}

控制器:

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做前后端分离





    
    王家乐-仿京东实战
    
 
    
    



{{result.price}}

{{result.name}}

店铺: Java

月成交999笔 评价 3

启动类:

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);
    }

}

最终效果图:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/327529.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号