SpringBoot+Elasticsearch

1.  前言

1.1.  集成方式

Spring Boot中集成Elasticsearch有4种方式:

  1. REST Client
  2. Jest
  3. Spring Data
  4. Spring Data Elasticsearch Repositories

本文用后面两种方式来分别连接并操作Elasticsearch

1.2.  环境与配置

服务端:elasticsearch-6.3.2    1台

客户端:elasticsearch 6.4.1

服务端配置文件:elasticsearch.yml

cluster.name: my-application
network.host: 192.168.1.134
http.port: 9200

/etc/security/limits.conf

cheng soft nofile 65536
cheng hard nofile 65536

/etc/sysctl.conf

vm.max_map_count=262144

1.3.  版本

Spring Boot 2.0.5默认的elasticsearch版本很低,这里我们用最新版本6.4.1

如果启动过程中出现

java.lang.NoClassDefFoundError: org/elasticsearch/common/transport/InetSocketTransportAddress

则说明,elasticsearch依赖的jar包版本不一致,统一改成6.4.1即可

另外,Spring Boot 2.0.5依赖的spring-data-elasticsearch版本是3.0.1,需要升级到3.1.0

2.  依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    modelVersion>4.0.0</>

    groupId>com.cjs.exampleartifactId>cjs-elasticsearch-exampleversion>0.0.1-SNAPSHOTpackaging>jarnamedescription></parent>
        >org.springframework.boot>spring-boot-starter-parent>2.0.5.RELEASErelativePath/> <!-- lookup parent from repository -->
    propertiesproject.build.sourceEncoding>UTF-8project.reporting.outputEncodingjava.version>1.8>

        elasticsearch.version>6.4.1spring.data.elasticsearch.version>3.1.0.RELEASEdependenciesdependency>
            >org.elasticsearch>elasticsearch>${elasticsearch.version}>org.elasticsearch.client>transport>elasticsearch-rest-client>org.elasticsearch.plugin>transport-netty4-client>org.springframework.data>spring-data-elasticsearch>${spring.data.elasticsearch.version}>spring-boot-starter-data-elasticsearch>spring-boot-starter-web>org.projectlombok>lombokoptional>true>spring-boot-starter-testscope>testbuildpluginsplugin>
                >spring-boot-maven-plugin>

project>

3.  application.properties

spring.data.elasticsearch.cluster-name=my-application
spring.data.elasticsearch.cluster-nodes=192.168.1.134:9300

也许,大家会疑惑,配置文件中明明写的端口是9200,为何这里配置文件中连接的时候写的端口是9300呢?

因为,配置9200是通过HTTP连接的端口,9300是TCP连接的端口

4.  操作

4.1.  使用Spring Data Elasticsearch Repositories操作Elasticsearch

首先,定义一个实体类

package com.cjs.example.entity;

import lombok.Data;
 org.springframework.data.annotation.Id;
 org.springframework.data.elasticsearch.annotations.Document;

 java.io.Serializable;

@Data
@Document(indexName = "commodity")
public class Commodity implements Serializable {

    @Id
    private String skuId;

     String name;

     String category;

     Integer price;

     String brand;

     Integer stock;

}

这里定义了Commodity实例,表示商品。在Elasticsearch 6.X 版本中,不建议使用type,而且在7.X版本中将会彻底废弃type,所以此处我只指定了indexName,没有指定type。这里,一个Commodity代表一个商品,同时代表一条索引记录。

类比关系型数据库的话,Index相当于表,Document相当于记录

 

然后,需要自己定义一个接口,并继承ElasticsearchRepository

 com.cjs.example.dao;

 com.cjs.example.entity.Commodity;
 org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
 org.springframework.stereotype.Repository;

@Repository
interface CommodityRepository extends ElasticsearchRepository<Commodity,String> {

}

这里的Repository相当于DAO,操作mysql还是elasticsearch都是一样的

接下来,定义service接口

 com.cjs.example.service;

 org.springframework.data.domain.Page;

 java.util.List;

interface CommodityService {

    long count();

    Commodity save(Commodity commodity);

    void delete(Commodity commodity);

    Iterable<Commodity> getAll();

    List<Commodity> getByName(String name);

    Page<Commodity> pageQuery(Integer pageNo,Integer pageSize,String kw);

}

实现类

 com.cjs.example.service.impl;

 com.cjs.example.dao.CommodityRepository;
 com.cjs.example.service.CommodityService;
 org.elasticsearch.index.query.MatchQueryBuilder;
 org.elasticsearch.index.query.QueryBuilders;
 org.springframework.beans.factory.annotation.Autowired;
 org.springframework.data.domain.Page;
 org.springframework.data.domain.PageRequest;
 org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
 org.springframework.data.elasticsearch.core.query.SearchQuery;
 org.springframework.stereotype.Service;

 java.util.ArrayList;
 java.util.List;

@Service
class CommodityServiceImpl  CommodityService {

    @Autowired
     CommodityRepository commodityRepository;


    @Override
     count() {
        return commodityRepository.count();
    }

    @Override
    public Commodity save(Commodity commodity) {
         commodityRepository.save(commodity);
    }

    @Override
     delete(Commodity commodity) {
        commodityRepository.delete(commodity);
//        commodityRepository.deleteById(commodity.getSkuId());
    }

    @Override
    public Iterable<Commodity> getAll() {
         commodityRepository.findAll();
    }

    @Override
    public List<Commodity> getByName(String name) {
        List<Commodity> list = new ArrayList<>();
        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("name",name);
        Iterable<Commodity> iterable = commodityRepository.search(matchQueryBuilder);
        iterable.forEach(e->list.add(e));
         list;
    }

    @Override
    public Page<Commodity>new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchPhraseQuery("name" commodityRepository.search(searchQuery);
    }


}

在这个Service中演示了增删查改操作,还有分页查询

最后,写一个测试类测试其中的方法

 com.cjs.example;

 org.junit.Test;
 org.junit.runner.RunWith;
 org.springframework.boot.test.context.SpringBootTest;
 org.springframework.test.context.junit4.SpringRunner;

 java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
 CjsElasticsearchExampleApplicationTests {

    @Autowired
     CommodityService commodityService;

    @Test
     contextLoads() {
        System.out.println(commodityService.count());
    }

    @Test
     testInsert() {
        Commodity commodity =  Commodity();
        commodity.setSkuId("1501009001");
        commodity.setName("原味切片面包(10片装)");
        commodity.setCategory("101");
        commodity.setPrice(880);
        commodity.setBrand("良品铺子");
        commodityService.save(commodity);

        commodity =  Commodity();
        commodity.setSkuId("1501009002");
        commodity.setName("原味切片面包(6片装)");
        commodity.setPrice(680 Commodity();
        commodity.setSkuId("1501009004");
        commodity.setName("元气吐司850g");
        commodity.setPrice(120);
        commodity.setBrand("百草味");
        commodityService.save(commodity);

    }

    @Test
     testDelete() {
        Commodity commodity = );
        commodityService.delete(commodity);
    }

    @Test
     testGetAll() {
        Iterable<Commodity> iterable = commodityService.getAll();
        iterable.forEach(e->System.out.println(e.toString()));
    }

    @Test
     testGetByName() {
        List<Commodity> list = commodityService.getByName("面包");
        System.out.println(list);
    }

    @Test
     testPage() {
        Page<Commodity> page = commodityService.pageQuery(0,10,"切片");
        System.out.println(page.getTotalPages());
        System.out.println(page.getNumber());
        System.out.println(page.getContent());
    }
}

以上,便是使用Elasticsearch Repositories的方式

4.2.  使用ElasticsearchTemplate方式操作Elasticsearch

 org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.*;
 ElasticsearchTemplateTest {

    @Autowired
     ElasticsearchTemplate elasticsearchTemplate;

    @Test
     Commodity();
        commodity.setSkuId("1501009005");
        commodity.setName("葡萄吐司面包(10片装)");
        commodity.setPrice(160);

        IndexQuery indexQuery =  IndexQueryBuilder().withObject(commodity).build();
        elasticsearchTemplate.index(indexQuery);
    }

    @Test
     testQuery() {
        SearchQuery searchQuery =  NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery("name","吐司"))
                .build();
        List<Commodity> list = elasticsearchTemplate.queryForList(searchQuery,Commodity.);
        System.out.println(list);
    }

}

ElasticsearchTemplate是自动配置的

 

5.  演示

 

6. 工程结构

 

 

7.  参考

https://docs.spring.io/spring-data/elasticsearch/docs/3.1.0.RELEASE/reference/html/#repositories.query-methods.details

 

相关文章

今天小编给大家分享的是Springboot下使用Redis管道(pipeline...
本篇文章和大家了解一下springBoot项目常用目录有哪些。有一...
本篇文章和大家了解一下Springboot自带线程池怎么实现。有一...
这篇文章主要介绍了SpringBoot读取yml文件有哪几种方式,具有...
今天小编给大家分享的是SpringBoot配置Controller实现Web请求...
本篇文章和大家了解一下SpringBoot实现PDF添加水印的方法。有...