SpringBoot整合Elasticsearch

SpringBoot整合Elasticsearch

SpringBoot整合Elasticsearch有以下几种方式:

  1. 使用官方的Elasticsearch Java客户端进行集成
    • 通过添加Elasticsearch Java客户端的依赖,可以直接在Spring Boot应用中使用原生的Elasticsearch API进行操作。
    • 参考文档
  2. 使用Spring Data Elasticsearch进行集成
    • Spring Data Elasticsearch是Spring Data项目的一部分,提供了更高级的抽象和易用性,可以简化与Elasticsearch的交互。
    • 通过添加Spring Data Elasticsearch的依赖,可以使用Repository接口和注解来定义和执行CRUD操作。
    • 官方文档

本文使用第一种方式。使用官方推荐的RestHighLevelClient操作ES。由于版本兼容问题,请选择和Elasticsearch对应的Java客户端版本。

使用官方的Elasticsearch Java客户端进行集成

依赖

在这里插入图片描述
从官方文档可以知道需要导入org.elasticsearch:elasticsearch和org.elasticsearch.client:elasticsearch-rest-client。


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.4.2</version>
        </dependency>

        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

配置

@Configuration
public class ESConfig {

    /**
     * 解决netty引起的issue
     */
    @PostConstruct
    void init() {
        System.setProperty("es.set.netty.runtime.available.processors", "false");
    }


    @Bean
    public RestHighLevelClient getRestClient() {

        RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient
                .builder(new HttpHost("192.168.200.200", 9200, "http")));
        return restHighLevelClient;
    }

}

创建索引

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 创建索引
     */
    @Test
    public void createIndex1() {
        String result = "创建成功";
        CreateIndexRequest createIndexRequest = new CreateIndexRequest("stu");
        try {
            CreateIndexResponse createIndexResponse = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);

            if (!createIndexResponse.isAcknowledged()){
                result = "创建失败";
            }else{
                result = "索引已经存在";
            }
        } catch (IOException e) {
            e.printStackTrace();
            result = "接口异常";
        }

        System.out.println(result);
    }
   /**
     * 创建索引同时创建映射关系
     * 如索引存在:新增文档数据;如果索引不存在:创建一条索引
     */
    @Test
    public void createIndex2() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("user", "kimchyrw");
        map.put("postDate", new Date());
        map.put("message", "trying out Elasticsearch");

        IndexRequest request = new IndexRequest("posts")
                .id("2").source(map, XContentType.JSON);

        try {
            //响应信息
            IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
            String index = indexResponse.getIndex();
            String id = indexResponse.getId();
            System.out.println("index: " + index + " id: " + id);
            //创建索引还是更新索引
            if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
                System.out.println("CREATED.....");
            } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
                System.out.println("UPDATED....");
            }
            //校验分片信息
            ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
            if (shardInfo.getTotal() != shardInfo.getSuccessful()){

            }
            if (shardInfo.getFailed() > 0) {
                for (ReplicationResponse.ShardInfo.Failure failure :shardInfo.getFailures()) {
                    String reason = failure.reason();
                    System.out.println("reason: " + reason);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

更新文档中的数据

    /**
     * 更新一行数据
     */
    @Test
    public void updateDoc() {
        //更新的数据
        HashMap<String, Object> map = new HashMap<>();
        map.put("updated", new Date());
        map.put("user", "kimchyrw");
        map.put("reason", "daily update");
        UpdateRequest updateRequest = new UpdateRequest("posts", "2")
                .doc(map);
        try {
            UpdateResponse updateResponse = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
            String index = updateResponse.getIndex();
            String id = updateResponse.getId();
            long version = updateResponse.getVersion();
            if (updateResponse.getResult() == DocWriteResponse.Result.CREATED) {
                System.out.println("CREATED");
            } else if (updateResponse.getResult() == DocWriteResponse.Result.UPDATED) {
                System.out.println("UPDATED");
            } else if (updateResponse.getResult() == DocWriteResponse.Result.DELETED) {
                System.out.println("DELETED");
            } else if (updateResponse.getResult() == DocWriteResponse.Result.NOOP) {
                System.out.println("NOOP");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

查询

   /**
     * 根据id查询document
     */
    @Test
    public void getApi() {
        GetRequest getRequest = new GetRequest("posts", "1");
        //可选参数
        //禁用源检索,默认启用,开启后检索不到数据
       // getRequest.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE);

        try {
            GetResponse getResponse = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
            String index = getResponse.getIndex();
            String id = getResponse.getId();
            System.out.println("index: " + index + " id: " + id);
            if (getResponse.isExists()) {
                long version = getResponse.getVersion();
                String sourceAsString = getResponse.getSourceAsString();
                Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
                byte[] sourceAsBytes = getResponse.getSourceAsBytes();
                System.out.println("version: " + version);
                System.out.println("sourceAsMap: " + sourceAsMap);
                System.out.println("sourceAsBytes: " + Arrays.toString(sourceAsBytes));
                System.out.println("sourceAsString: " + sourceAsString);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   /**
     * 根据指定字段查询document
     */
    @Test
    public void testSearch2() {
        SearchRequest searchRequest = new SearchRequest("posts");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //根据指定字段查询
        searchSourceBuilder.query(QueryBuilders.termQuery("user", "kimchy"));
        //分页查询记录
        searchSourceBuilder.from(0);
        searchSourceBuilder.size(5);
        //设置超时时间
       // searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //按字段排序或者按评分排序
        searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
        searchSourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.ASC));

        //结果高亮

        //查询部分字段
        searchSourceBuilder.fetchSource(new String[]{"user"}, new String[]{"user1"});
        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            RestStatus status = searchResponse.status();
            TimeValue took = searchResponse.getTook();
            Boolean terminatedEarly = searchResponse.isTerminatedEarly();
            boolean timedOut = searchResponse.isTimedOut();

            SearchHits hits = searchResponse.getHits();
            TotalHits totalHits = hits.getTotalHits();
            long numHits = totalHits.value;
            TotalHits.Relation relation = totalHits.relation;
            float maxScore = hits.getMaxScore();
            System.out.println("hits: " + hits + " totalHits: " + totalHits + " numHits: " + numHits + " maxScore: " + maxScore);
            SearchHit[] searchHits = hits.getHits();
            for (SearchHit hit: searchHits) {
                String id = hit.getId();
                System.out.println("id: " + id);
                String sourceAsString = hit.getSourceAsString();
                System.out.println(sourceAsString);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

使用Spring Data Elasticsearch进行集成

依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

创建实体类

启动后会自动创建索引foodie-items

@Data
@Document(indexName = "foodie-items", createIndex = true)
public class Items {

    @javax.persistence.Id
    private String id;

    @Field(type = FieldType.Text)
    private String itemId;

    @Field(type = FieldType.Text)
    private String itemName;

    @Field(type = FieldType.Text)
    private String imgUrl;

    @Field(type = FieldType.Double)
    private Integer price;

    @Field(type = FieldType.Integer)
    private Integer sellCounts;

    @Field(type = FieldType.Integer)
    private Integer catId;

    @Field(type = FieldType.Integer)
    private Integer rootCatId;

    @Field(type = FieldType.Integer)
    private Integer onOffStatus;

    @Field(type = FieldType.Date, format = DateFormat.basic_date_time)
    private Date createdTime;

    @Field(type = FieldType.Date, format = DateFormat.basic_date_time)
    private Date updatedTime;

    @Field(type = FieldType.Text)
    private String content;

}

继承接口

继承ElasticsearchRepository接口后,可以在接口中自定义方法,也可以使用接口提供的方法进行查询。和JPA的使用是类似的。

/**
 * 在实体类上使用注解,然后继承ElasticsearchRepository接口, 启动后会自动创建索引
 */
@Repository("esFoodItemsRepository")
public interface EsFoodItemsRepository extends ElasticsearchRepository<Items, String> {
}

Elasticsearch Operations使用

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    @Test
    public void test2() {
        Items items = elasticsearchOperations.get("1", Items.class);
        System.out.println("items: " + items);
    }

Elasticsearch Operations

参考

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是SpringBoot整合elasticsearch的步骤: 1. 引入elasticsearchspring-boot-starter-data-elasticsearch的依赖: ``` <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>7.12.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> <version>2.4.5</version> </dependency> ``` 2. 配置elasticsearch连接信息: ``` spring.data.elasticsearch.cluster-nodes=localhost:9200 ``` 3. 创建实体类: ``` @Document(indexName = "my_index") public class MyEntity { @Id private String id; private String name; // getter and setter } ``` 4. 创建es的Repository: ``` public interface MyRepository extends ElasticsearchRepository<MyEntity, String> { } ``` 5. 在service中使用Repository: ``` @Service public class MyService { @Autowired private MyRepository myRepository; public void save(MyEntity entity) { myRepository.save(entity); } public List<MyEntity> search(String name) { return myRepository.findByName(name); } } ``` 6. 在controller中调用service: ``` @RestController public class MyController { @Autowired private MyService myService; @PostMapping("/save") public void save(@RequestBody MyEntity entity) { myService.save(entity); } @GetMapping("/search") public List<MyEntity> search(@RequestParam String name) { return myService.search(name); } } ``` 这样就可以通过SpringBoot整合elasticsearch实现数据的增删改查了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值