SpringBoot整合Elasticsearch

9 篇文章 0 订阅
5 篇文章 0 订阅

一、配置pom

pom.xml
在这里插入图片描述
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.li</groupId>
	<artifactId>li-es-api</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>li-es-api</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
		<repackage.classifier/>
		<spring-native.version>0.10.1</spring-native.version>
		<!--更改默认es版本-->
		<elasticsearch.version>7.8.0</elasticsearch.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.62</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.springframework.experimental</groupId>
			<artifactId>spring-native</artifactId>
			<version>${spring-native.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.0.5</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
					<classifier>${repackage.classifier}</classifier>
					<image>
						<builder>paketobuildpacks/builder:tiny</builder>
						<env>
							<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
						</env>
					</image>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.experimental</groupId>
				<artifactId>spring-aot-maven-plugin</artifactId>
				<version>${spring-native.version}</version>
				<executions>
					<execution>
						<id>test-generate</id>
						<goals>
							<goal>test-generate</goal>
						</goals>
					</execution>
					<execution>
						<id>generate</id>
						<goals>
							<goal>generate</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
	<repositories>
		<repository>
			<id>spring-releases</id>
			<name>Spring Releases</name>
			<url>https://repo.spring.io/release</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>spring-releases</id>
			<name>Spring Releases</name>
			<url>https://repo.spring.io/release</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</pluginRepository>
	</pluginRepositories>

	<profiles>
		<profile>
			<id>native</id>
			<properties>
				<repackage.classifier>exec</repackage.classifier>
				<native-buildtools.version>0.9.1</native-buildtools.version>
			</properties>
			<dependencies>
			</dependencies>
			<build>
				<plugins>
				</plugins>
			</build>
		</profile>
	</profiles>

</project>

二、编写配置文件

ElasticSearchConfig.java


@Configuration
public class ElasticSearchConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")));
                        //new HttpHost("localhost", 9201, "http")));
                return client;
    }
    static BulkProcessor getProcessor(){
        BiConsumer<BulkRequest, ActionListener<BulkResponse>> client = null;
        return BulkProcessor.builder(client, new BulkProcessor.Listener() {

            @Override
            public void beforeBulk(long l, BulkRequest bulkRequest) {

            }

            @Override
            public void afterBulk(long l, BulkRequest bulkRequest, BulkResponse bulkResponse) {

            }

            @Override
            public void afterBulk(long l, BulkRequest bulkRequest, Throwable throwable) {

            }
        })//设置提交批处理操作的请求阀值数
                .setBulkActions(20000)
                //设置提交批处理操作的操作的请求大小阀值
                .setBulkSize(new ByteSizeValue(500, ByteSizeUnit.MB))
                // 设置刷新索引时间间隔
                .setFlushInterval(TimeValue.timeValueSeconds(30))
                //设置并发处理的线程个数
                .setConcurrentRequests(30)
                //设置回滚策略,等待时间1000ms,retry次数1次
                .setBackoffPolicy(BackoffPolicy.exponentialBackoff(
                        TimeValue.timeValueMillis(1000), 1))
                .build();

    }

}

三、编写测试函数

test.java


@SpringBootTest
class LiEsApiApplicationTests {
    @Autowired
    @Qualifier("restHighLevelClient")
    private RestHighLevelClient client;
    @Autowired
    MmsMemberCompanyService mmsMemberCompanyService;
    @Autowired
    AssociationinfoService associationinfoService;
    /*或者
     *@Autowired
     *private RestHighLevelClient restHighLevelClient;
     * */


    //索引创建
    @Test
    void testCreateIndex() throws IOException {
        //1 创建索引
        CreateIndexRequest request = new CreateIndexRequest("li_index");
        //2 客户端执行请求 IndicesClient 获得响应
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }

    //索引获取
    @Test
    void testGetIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("li_index");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    //索引删除
    @Test
    void testDelIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("li_index");
        AcknowledgedResponse delete = client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println(delete.isAcknowledged());
    }


    //添加文档
    @Test
    void testAddDoc() throws IOException {
        User user = new User("li", 23);
        IndexRequest request = new IndexRequest("li_index");
        //规则 PUT /li_index/_doc/1
        request.id("1");
        request.timeout(TimeValue.timeValueSeconds(1));//request.timeout("1s");
        //数据放入请求
        IndexRequest source = request.source(JSON.toJSONString(user), XContentType.JSON);
        //客户端发送请求
        IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
        System.out.println(indexResponse.toString());
        System.out.println(indexResponse.status());


    }


    //获取文档   GET /index/_doc/1
    @Test
    void testIsExistDoc() throws IOException {
        GetRequest request = new GetRequest("li_index", "1");
        //不获取返回的_source的上下文
        request.fetchSourceContext(new FetchSourceContext(false));
        request.storedFields("");

        boolean exists = client.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }

    //获取文档信息
    @Test
    void testGetDoc() throws IOException {
        GetRequest request = new GetRequest("li_index", "1");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        System.out.println(response.getSourceAsString());
        System.out.println(response);//和命令式 返回内容一样
    }

    //更新文档信息
    @Test
    void testUpdateDoc() throws IOException {
        UpdateRequest request = new UpdateRequest("li_index", "1");
        request.timeout("1s");

        User user = new User("张三", 56);
        UpdateRequest doc = request.doc(JSON.toJSONString(user), XContentType.JSON);
        UpdateResponse updateResponse = client.update(doc, RequestOptions.DEFAULT);
        System.out.println(updateResponse.status());
        System.out.println(updateResponse);//和命令式 返回内容一样
    }

    //删除文档记录
    @Test
    void testDelDoc() throws IOException {
        DeleteRequest request = new DeleteRequest("li_index", "1");
        request.timeout("1s");
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(response.status());
    }

    //批量插入
    @Test
    void testBulkAddDoc() throws IOException {
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("10s");

        ArrayList<User> users = new ArrayList<>();
        users.add(new User("java", 15));
        users.add(new User("C", 16));
        users.add(new User("C++", 17));
        users.add(new User("python", 18));
        users.add(new User("js", 19));
        users.add(new User("es", 25));
        users.add(new User("SSm", 35));
        users.add(new User("cloud", 45));

        for (int i = 0; i < users.size(); i++) {
            bulkRequest.add(new IndexRequest("li_index")
                    .source(JSON.toJSONString(users.get(i)), XContentType.JSON)
            );
        }
        BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        System.out.println(bulk.hasFailures());
    }


    //查询
    // SearchRequest搜索请求
    // SearchSourceBuilder条件构造
    // HighLightBuilder构建高亮
    //TermQueryBuilder精确查询
    // /MatchALLQueryBuilder
    //xxx QueryBuilder对应命令

    //查询
    @Test
    void testSearch() throws IOException {
        SearchRequest request = new SearchRequest(ESconst.ES_INDEX);
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //QueryBuilder queryBuilder = new QueryBuilder(); 不推荐
        //QueryBuilders 工具类永远的神
        TermQueryBuilder builder = QueryBuilders.termQuery("name", "java");
        searchSourceBuilder.query(builder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

        request.source(searchSourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(search.getHits()));
        System.out.println("===============");
        for (SearchHit hit : search.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
    }

    //批量插入
    @Test
    void testBulkAddDocTest2() throws IOException {


        int itemCount;
        int doCount = 1;
        do {
            List<MmsMemberCompany> mmsMemberCompanies = mmsMemberCompanyService.selectAll();
            itemCount = mmsMemberCompanies.size();
            if (itemCount > 0) {
                BulkRequest bulkRequest = new BulkRequest();
                bulkRequest.timeout("10s");
                for (int i = 0; i < mmsMemberCompanies.size(); i++) {
                    MmsMemberCompany mmsMemberCompany = mmsMemberCompanies.get(i);
                    bulkRequest.add(new IndexRequest("mmsmembercompany_index")
                            .source(JSON.toJSONString(mmsMemberCompany), XContentType.JSON)
                            .id(mmsMemberCompany.getId())
                    );
                    System.out.println("===================" + "i=" + i);
                }
                System.out.println("执行次数:" + doCount);
                doCount++;
                BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
                System.out.println(bulk.hasFailures());
                Associationinfo associationinfo = new Associationinfo("test", mmsMemberCompanies.get(itemCount - 1).getUpdateTime(), 1);
                associationinfoService.updateInfo(associationinfo);
            }
        } while (itemCount == 3000);
    }

四、项目运用

4.1 编写pojo类

@EqualsAndHashCode(callSuper = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ESCompanyListReq extends StartPage {

    @NotNull
    String name;

    Long legalEntityId;

    String creditCode;

    Long id;

}

4.2 编写service类

@Service
public interface CompanySearchService {

    /**
     * @Description:模糊搜索-结果分页-内容高亮显示-按公司名字
     * @Author: lya
     * @Date: 2021/7/22 14:53
     * @Param:ESCompany
     * @Return:ESCompany
     */
    public List<ESCompanyListReq> searchCompanyPageHighLight(ESCompanyListReq param) throws IOException;


}
@Slf4j
@Service
public class CompanySearchServiceImpl implements CompanySearchService {
    @Resource
    private RestHighLevelClient restHighLevelClient;

    @Override
    //模糊搜索company-结果分页-内容高亮显示
    public List<ESCompanyListReq> searchCompanyPageHighLight(ESCompanyListReq param) throws IOException {
        SearchRequest searchRequest = new SearchRequest(ES_INDEX_company);
        //ES_INDEX_company 为静态常量自己配置即可,对应索引名称
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //分页
        searchSourceBuilder.from(param.getPageIndex());
        searchSourceBuilder.size(param.getPageSize());
        //模糊匹配
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", param.getName());
        searchSourceBuilder.query(matchQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.requireFieldMatch(true);
        highlightBuilder.preTags("<span style= 'color: red'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);
        //执行搜索
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //解析结果

        ArrayList<Map<String, Object>> list = new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            //解析高亮字段
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();//原来的结果
            //原来的字段换成现在的高亮字段
            if (name != null) {
                Text[] fragments = name.fragments();
                String replace = "";
                for (Text fragment : fragments) {
                    replace += fragment;
                }
                sourceAsMap.put("name", replace);
            }
            list.add(sourceAsMap);
        }
        ArrayList<ESCompanyListReq> esCompanies = new ArrayList<>();
        for (Map<String, Object> map : list) {
            String s = JSON.toJSONString(map);//-->Map集合转换成JSON字符串
            ESCompanyListReq esCompany = JSON.parseObject(s, ESCompanyListReq.class);//将JSON字符串转换成实体类
            esCompanies.add(esCompany);
        }
        return esCompanies;
    }
}

4.3 编写controller类

@Slf4j
@RestController
@RequestMapping("/search")
public class IndexSearchController {
    @Resource
    CompanySearchService companySearchService;

    @PostMapping("/listCompanyByCompanyName")
    public Result CompanySearch(@Validated @RequestBody ESCompanyListReq req) throws IOException {
        List<ESCompanyListReq> esCompanies = companySearchService.searchCompanyPageHighLight(req);
        return Result.success(esCompanies);
    }
}

4.4 测试

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值