使用Spring Data ElasticSearch对ElasticSearch进行CRUD以及分页操作

ElasticSearch的介绍与安装
对ElasticSearch进行原生的CRUD以及分页操作
什么是Spring Data ElasticSearch
Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快 捷,并支持map-reduce框架和云计算数据服务。 Spring Data可以极大的简化JPA的写法,可以在几乎不用写实现 的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。
Spring Data的官网:http://projects.spring.io/spring-data/

使用Spring Data ElasticSearch对ElasticSearch进行CRUD以及分页操作

  1. pom文件
        <!--添加elasticsearch坐标-->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>5.6.8</version>
        </dependency>
        <!--添加elasticsearch客户端坐标-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>5.6.8</version>
        </dependency>
        <!--Spring Data ElasticSearch坐标-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-elasticsearch</artifactId>
            <version>3.0.5.RELEASE</version>
            <exclusions>
                <exclusion>
                    <groupId>org.elasticsearch.plugin</groupId>
                    <artifactId>transport-netty4-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.41</version>
        </dependency>
        <!--测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>
  1. 配置文件【applicationContext.xml】
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:elasticsearch="http://www.springframework.org/schema/data/elasticsearch"
       xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/data/elasticsearch
		http://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd
		">

	<!-- 配置server包扫描 -->
	<context:component-scan base-package="com.test.server"/>

	<!--
	配置elasticSearch的连接
		cluster-nodes:配置节点信息  配置节点信息 多个节点之间用逗号隔开 例:cluster-nodes="localhost:9300,localhost:9400"
		cluster-name:配置集群名   默认为elasticsearch
	-->
	<elasticsearch:transport-client id="client" cluster-nodes="localhost:9300" cluster-name="elasticsearch"/>

	<!-- ElasticSearch模版对象 -->
	<bean id="elasticsearchTemplate" class="org.springframework.data.elasticsearch.core.ElasticsearchTemplate">
		<constructor-arg name="client" ref="client"></constructor-arg>
	</bean>

	<!-- 配置Dao包扫描 -->
	<elasticsearch:repositories base-package="com.test.dao"/>

</beans>
  1. entity实体类
package com.test.entity;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

/**
 * 创建一个Elasticsearch文档的实体类对象
 */
//文档对象   indexName: 索引名  type: 类型名
@Document(indexName = "data_es_blog", type = "data_es_article")
public class EsDocument {
    @Id //文档主键    唯一的标识
    //字段配置 store: 是否存储  index: 是否索引   type: 字段类型
    @Field(store = true, index = false, type = FieldType.Long)
    private Long id; //id
    //字段配置 analyzer: 插入文档时是否分词,并指定分词器 searchAnalyzer: 查询时是否分词,并指定分词器   注意:不指定使用默认标准分词器
    @Field(store = true, index = true, analyzer = "ik_smart", searchAnalyzer = "ik_smart", type = FieldType.text)
    private String title; //标题
    @Field(store = true, index = true, analyzer = "ik_smart", searchAnalyzer = "ik_smart", type = FieldType.text)
    private String content; //内容

    public EsDocument() {
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "EsDocument{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

  1. dao层
    如果自定义方法,满足Spring Data ElasticSearch的命名规则,所以只需要定义接口,不需要实现,命名规则图会放在最后
    注意
    1. Spring Data ElasticSearch的查询会先分词在查询 但是分词之后的多个关键词之间的使用and连接也就是说需要满足所有的关键词才会查询出
    2. 使用ElasticSearch原生查询在查询时也是先分词在查询 但是分词之后的多个关键字为or或者的关系也就是说只要满足其中一个关键字即可查询到
package com.test.dao;

import com.test.entity.EsDocument;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface EsDao extends ElasticsearchRepository<EsDocument, Long> {//指定实体类和id类型

    /**
     * 根据title作用域来查询    参数title:在title域进行检索的关键字
     *
     * 此方法是按照Spring Data ElasticSearch的命名规则来写的,所以只需要定义接口,不需要实现
     * 此查询会先分词在查询  但是分词之后的多个关键词之间的使用and连接
     *  也就是说需要满足所有的关键词才会查询出
     * @param title
     * @return
     */
    List<EsDocument> findEsDocumentByTitle(String title);

    /**
     * 根据title和content作用域来查询    需同时满足
     *      参数title:在title域进行检索的关键字
     *      参数content:在content域进行检索的关键字
     * 此方法是按照Spring Data ElasticSearch的命名规则来写的,所以只需要定义接口,不需要实现
     * 此查询会先分词在查询  但是分词之后的多个关键词之间的使用and连接
     *  也就是说需要满足所有的关键词才会查询出
     * @param title
     * @param content
     * @return
     */
    List<EsDocument> findEsDocumentByTitleAndContent(String title,String content);
}

  1. server层
package com.test.server;

import com.test.entity.EsDocument;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

public interface EsServer {
    //保存文档
    EsDocument save(EsDocument esDocument);

    //更新文档
    void update(EsDocument esDocument);

    //根据ID删除
    void deleteById(Long id);

    //根据对象删除文档
    void delete(EsDocument esDocument);

    //删除全部
    void deleteAll();

    //根据id查询
    EsDocument findById(Long id);

    //根据id组查询
    List<EsDocument> findAllById(List<Long> ids);

    //查询所有
    List<EsDocument> findAll();

    //自定义查询 根据title作用域来查询
    List<EsDocument> findEsDocumentByTitle(String title);

    //自定义查询 根据title和content作用域来查询
    List<EsDocument> findEsDocumentByTitleAndContent(String title,String content);

    //分页查询
    List<EsDocument> findAllByPage1(Pageable pageable);

    //分页查询
    Page<EsDocument> findAllByPage2(Pageable pageable);
}


  1. 实现类 impl
package com.test.server.impl;

import com.test.dao.EsDao;
import com.test.entity.EsDocument;
import com.test.server.EsServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

@Service
public class EsServerImpl implements EsServer {
    @Autowired
    private EsDao esDao;

    /**
     * 保存文档
     *
     * @param esDocument
     */
    public EsDocument save(EsDocument esDocument) {
        EsDocument save = esDao.save(esDocument);
        return save;
    }

    /**
     * 更新文档
     *
     * @param esDocument
     */
    public void update(EsDocument esDocument) {
        esDao.save(esDocument);
    }

    /**
     * 根据ID删除
     *
     * @param id
     */
    public void deleteById(Long id) {
        esDao.deleteById(id);
    }

    /**
     * 删除文档
     *
     * @param esDocument
     * @return
     */
    public void delete(EsDocument esDocument) {
        esDao.delete(esDocument);
    }

    /**
     * 删除全部
     */
    public void deleteAll() {
        esDao.deleteAll();
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public EsDocument findById(Long id) {
        Optional<EsDocument> result = esDao.findById(id);
        return result.get();
    }

    /**
     * 根据id组  查询数据
     *
     * @param ids
     * @return
     */
    @Override
    public List<EsDocument> findAllById(List<Long> ids) {
        Iterable<EsDocument> results = esDao.findAllById(ids);
        //遍历结果集
        return traverseResult(results);
    }

    /**
     * 查询所有
     *
     * @return
     */
    @Override
    public List<EsDocument> findAll() {
        Iterable<EsDocument> results = esDao.findAll();
        //遍历结果集
        return traverseResult(results);
    }

    /**
     * 自定义查询 根据title作用域来查询
     *
     * @param title
     * @return
     */
    @Override
    public List<EsDocument> findEsDocumentByTitle(String title) {
        return esDao.findEsDocumentByTitle(title);
    }

    /**
     * 自定义查询 根据title和content作用域来查询
     *
     * @param title
     * @param content
     * @return
     */
    @Override
    public List<EsDocument> findEsDocumentByTitleAndContent(String title, String content) {
        return esDao.findEsDocumentByTitleAndContent(title, content);
    }

    /**
     * 分页查询
     *
     * @return
     */
    public List<EsDocument> findAllByPage1(Pageable pageable) {
        Iterable<EsDocument> results = esDao.findAll(pageable);
        //遍历结果集
        return traverseResult(results);
    }

    /**
     * 分页查询
     *
     * @param pageable
     * @return
     */
    @Override
    public Page<EsDocument> findAllByPage2(Pageable pageable) {
        return esDao.findAll(pageable);
    }

    /**
     * 遍历结果集
     *
     * @return
     */
    public List<EsDocument> traverseResult(Iterable<EsDocument> results) {
        List<EsDocument> list = new ArrayList<>();
        Iterator<EsDocument> iterator = results.iterator();
        //遍历结果
        while (iterator.hasNext()) {
            //获取到对象
            EsDocument esDocument = iterator.next();
            list.add(esDocument);
        }
        return list;
    }
}


  1. 测试
import com.test.entity.EsDocument;
import com.test.server.EsServer;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Arrays;
import java.util.List;

/**
 * 使用Spring Data ElasticSearch对ElasticSearch进行CRUD以及分页
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class DataElasticSearchTest {
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    private EsServer esServer;

    /**
     * 使用ElasticsearchTemplate模板创建索引和映射
     */
    @Test
    public void createIndex() {
        //创建索引 注意:顺序不要搞反了
        elasticsearchTemplate.createIndex(EsDocument.class);
        //设置映射  注意:顺序不要搞反了
        elasticsearchTemplate.putMapping(EsDocument.class);
    }

    /**
     * 创建文档
     */
    @Test
    public void save() {
        EsDocument esDocument = new EsDocument();
        //设置文档id
        esDocument.setId(1L);
        //设置文档标题
        esDocument.setTitle("易卜生");
        //设置文档内容
        esDocument.setContent("不因幸运而固步自封,不因厄运而一蹶不振。真正的强者,善于从顺境中找到阴影,从逆境中找到光亮,时时校准自己前进的目标。");
        //保存文档
        EsDocument save = esServer.save(esDocument);
        System.out.println(save.toString());
    }

    /**
     * 更新文档  就是根据id会把原来的删掉在重新添加一遍
     */
    @Test
    public void update() {
        EsDocument esDocument = new EsDocument();
        //设置文档id
        esDocument.setId(1L);
        //设置文档标题
        esDocument.setTitle("王勃");
        //设置文档内容
        esDocument.setContent("穷且益坚,不坠青云之志。");
        //保存文档
        esServer.update(esDocument);
    }

    /**
     * 根据ID删除
     */
    @Test
    public void deleteById() {
        esServer.deleteById(2L);
    }

    /**
     * 根据对象删除文档
     */
    @Test
    public void delete() {
        EsDocument esDocument = new EsDocument();
        esDocument.setId(3l);
        esServer.delete(esDocument);
    }

    /**
     * 删除全部
     */
    @Test
    public void deleteAll() {
        esServer.deleteAll();
    }

    /**
     * 根据id查询
     */
    @Test
    public void findById() {
        EsDocument esDocument = esServer.findById(1L);
        System.out.println(esDocument);
    }

    /**
     * 根据id组查询
     */
    @Test
    public void findAllById() {
        //Long[] idArray = {1L, 2L, 4L};
        Long[] idArray = {9L, 10L, 11L};
        List<EsDocument> list = esServer.findAllById(Arrays.asList(idArray));
        System.out.println(list.toString());
    }

    /**
     * 查询所有
     */
    @Test
    public void findAll() {
        List<EsDocument> list = esServer.findAll();
        System.out.println(list.toString());
    }

    /**
     * 自定义查询 根据title作用域来查询
     * <p>
     * 自定义查询
     * 1. 需要按照Spring Data ElasticSearch的命名规则来写
     * 2. 只需要定义方法无需实现
     * 3. 自定义查询会先分词在查询  但是分词之后的多个关键词之间的使用and连接
     * 也就是说需要满足所有的关键词才会查询出
     *
     * 注意:此查询和ElasticSearch的原生查询  一定要区分开
     */
    @Test
    public void findEsDocumentByTitle() {
        List<EsDocument> list = esServer.findEsDocumentByTitle("王勃");
        System.out.println(list.toString());
    }

    /**
     * 自定义查询 根据title和content作用域来查询
     * <p>
     * 自定义查询
     * 1. 需要按照Spring Data ElasticSearch的命名规则来写
     * 2. 只需要定义方法无需实现
     * 3. 自定义查询会先分词在查询  但是分词之后的多个关键词之间的使用and连接
     * 也就是说需要满足所有的关键词才会查询出
     *
     *  注意:此查询和ElasticSearch的原生查询  一定要区分开
     */
    @Test
    public void findEsDocumentByTitleAndContent() {
        List<EsDocument> list = esServer.findEsDocumentByTitleAndContent("易卜生", "不因幸运而固步自封,不因厄运而一蹶不振");
        System.out.println(list.toString());
    }

    /**
     * 自定义查询
     *  使用ElasticSearch原生查询
     *      1. 可以自定义查询条件
     *      2. 在查询时也是先分词在查询   但是分词之后的多个关键字为or或者的关系
     *          也就是说只要满足其中一个关键字即可查询到
     *
     *  注意:此查询和Spring Data ElasticSearch的自定义查询  一定要区分开
     */
    @Test
    public void nativeSearchQuery() {
        //创建SearchQuery对象
        SearchQuery query = new NativeSearchQueryBuilder()
                //设置查询条件    以及查询的默认作用域
                .withQuery(QueryBuilders.queryStringQuery("真正的强者,善于从顺境中找到阴影,从逆境中找到光亮").defaultField("content"))
                //设置分页
                .withPageable(PageRequest.of(0, 3))
                .build();
        //使用模板对象执行查询
        List<EsDocument> list = elasticsearchTemplate.queryForList(query, EsDocument.class);
        System.out.println(list.toString());
    }


    /**
     * 分页查询
     */
    @Test
    public void findAllByPage1() {
        //设置分页 从第几页开始,每页显示多少条
        Pageable pageable = PageRequest.of(0, 3);
        List<EsDocument> list = esServer.findAllByPage1(pageable);
        //  System.out.println(list.toString());
    }

    /**
     * 分页查询
     */
    @Test
    public void findAllByPage2() {
        //设置分页 从第几页开始,每页显示多少条
        Pageable pageable = PageRequest.of(0, 3);
        Page<EsDocument> esDocuments = esServer.findAllByPage2(pageable);
        for (EsDocument esDocument : esDocuments.getContent()) {
            System.out.println(esDocument);
        }
    }

    @After
    public void methodEnd() {
        System.out.println("执行成功.....");
    }

}


这是ElasticsearchRepository 继承CrudRepository类帮我们实现的CRUD方法
在这里插入图片描述
这是Spring Data ElasticSearch 自定义方法的命名规则
在这里插入图片描述

如有错误欢迎大家批评指正,谢谢

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值