Springboot 使用jpa整合 Elasticsearch

标签:

本文出自jvm123.com-java技术分享站:http://jvm123.com/2019/10/springboot-shi-yong.html

Springboot 整合 Elasticsearch 使用,需要加入以下依赖:

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

在需要保存在elasticsearch中的实体类上加入如下注解:

/**
 * @author yawn http://jvm123.com
 * 2019/10/29 15:24
 */
@Document(indexName = "es_test", type = "user")
public class User {

    @Id
    private long id;
    private String name;
    private int age;
    private String des;

使用@Document注解指定文档序列化后保存的index和type(索引和类型,可以类比mysql中的数据库名和数据表名称),使用@Id注解表示这个字段将会和序列化后文档中的_id字段的值相同(_id要求式String类型,这里可以是其他类型)。

完成这些工作之后,就可以使用jpa的Repository或者ElasticsearchTemplate对Elasticsearch进行操作了。具体使用如下:

jpa的Repository操作Elasticsearch

继承Repository建立一个接口:

/**
 * @author yawn http://jvm123.com
 * 2019/10/29 15:27
 */
public interface UserRepos extends CrudRepository<User, Long> {

}

然后就可以注入UserRepos进行操作了,当然,也可以继承其他repository,更多repository。操作示例如下:

    @Test
    public void test1() {
        for (int i = 0; i < 10; i++) {
            User user = userRepos.save(new User(i, "yawn", 12, "我是一个小学生,我唉学习。"));
            System.out.println(user);
        }
    }

    @Test
    public void test2() {
        Iterable<User> users = userRepos.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

    @Test
    public void test3() {
        Optional<User> userOp = userRepos.findById(2L);
        userOp.ifPresent(System.out::println);
    }

执行之后,查询结果输出如下:

 User{id=0, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=1, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=2, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=3, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=4, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=5, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=6, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=7, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=8, name='yawn', age=12, des='我是一个小学生,我唉学习。'}
 User{id=9, name='yawn', age=12, des='我是一个小学生,我唉学习。'}

ElasticsearchTemplate操作Elasticsearch

在spring的环境下,直接注入ElasticsearchTemplate即可使用,使用示例如下:

插入/更新数据和使用id查询数据如下:

    @Autowired
    ElasticsearchTemplate template;

    @Test
    public void test4() {
//        IndexQuery 新增或更新user
        User u = new User(123, "yawn", 12, "我是一个小学生,我唉学习。");
        IndexQuery indexQuery = new IndexQueryBuilder().withObject(u).build();
        String documentId = template.index(indexQuery);
        System.out.println(documentId);

//        GetQuery 按照id查询user
        GetQuery getQuery = new GetQuery();
        getQuery.setId("123");
        User user = template.queryForObject(getQuery, User.class);
        System.out.println(user);

    }

使用searchQuery进行复杂查询如下:


    @Test
    public void test5() {
        // 查询所有
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(
                        matchAllQuery()
                ).build();
        queryPrint(searchQuery);

        // 按字段查询
        SearchQuery searchQuery2 = new NativeSearchQueryBuilder()
                .withQuery(
                        matchQuery("name", "yawn")
                ).build();
        queryPrint(searchQuery2);

        // 分页查询
        SearchQuery searchQuery3 = new NativeSearchQueryBuilder()
                .withQuery(
                        matchQuery("name", "yawn")
                )
                .withPageable(
                        PageRequest.of(1, 2)
                ).build();
        queryPrint(searchQuery3);

        // 排序查询
        SortBuilder sortBuilder = SortBuilders.fieldSort("id").order(SortOrder.DESC);
        SearchQuery searchQuery4 = new NativeSearchQueryBuilder()
                .withQuery(
                        matchQuery("name", "yawn")
                )
                .withSort(sortBuilder)
                .build();
        queryPrint(searchQuery4);

        // 查询指定的列(字段)
        String[] include = {"name", "id"};
        FetchSourceFilter fetchSourceFilter = new FetchSourceFilter(include, null);   //两个参数分别是要显示的和不显示的
        SearchQuery searchQuery5 = new NativeSearchQueryBuilder()
                .withSourceFilter(fetchSourceFilter)
                .build();
        queryPrint(searchQuery5);

        // 使用过滤器查询
        SearchQuery searchQuery6 = new NativeSearchQueryBuilder()
                .withFilter(
                        boolQuery().must(matchQuery("id", 123))
                )
                .build();
        queryPrint(searchQuery6);

        SearchQuery searchQuery7 = new NativeSearchQueryBuilder()
                .withFilter(
                        boolQuery().must(
                                matchQuery("name", "yawn")
                        )
                        .filter(
                                rangeQuery("id").gt(8)
                        )
                )
                .build();
        queryPrint(searchQuery7);

        // 短语查询
        SearchQuery searchQuery8 = new NativeSearchQueryBuilder()
                .withQuery(
                        matchPhraseQuery("des", "小学生")
                )
                .build();
        queryPrint(searchQuery8);

        // 高亮显示
        SearchQuery searchQuery9 = new NativeSearchQueryBuilder()
                .withQuery(
                        matchPhraseQuery("name", "yawn")
                )
                .withHighlightFields(new HighlightBuilder.Field("name"))
                .build();
        queryPrint(searchQuery9);
    }

    private void queryPrint(SearchQuery searchQuery) {
        List<User> users = template.queryForList(searchQuery, User.class);
        users.forEach(System.out::println);
        System.out.println();
    }

更多请参考官方文档: docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RELEASE/reference/html/#reference

发表评论