SpringBoot项目通过 spring data elasticsearch使用elasticsearch

依赖添加

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

配置添加

spring.data.elasticsearch.cluster-nodes=10.111.27.202:9300

实体标注

@Document(indexName = "resource", type = "resources")
public class Resource {
    private Long id;

    @Field(type = FieldType.text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String name;

    private String type;

    private Date createTime;
    private Date updateTime;

    private String url;

    private Integer readNumber;
    private Integer likeNumber;

    @Field(type = FieldType.text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String content;

    @Field(type = FieldType.text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
    private String writer;
    private String resource;

    private Date publishTime;

}

我们主要看@Document和@Field两个注解

这两个注解在springdata elasticsearch包下,springdata是spring的一项project,主要是封装了一个关系型数据库和非关系型数据库,比如MongoDB redis MySQL等,方便我们来使用。

package org.springframework.data.elasticsearch.annotations;

Document

Document对应的就是elasticsearch中的document

@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Document {

	String indexName();

	String type() default "";

	boolean useServerConfiguration() default false;

	short shards() default 5;

	short replicas() default 1;

	String refreshInterval() default "1s";

	String indexStoreType() default "fs";

	boolean createIndex() default true;
}

indexNmae 对应的是elasticsearch中的index,我们看到createIndex默认值是true,所以当elastic search中没有对应的index的时候会自己创建

document可以分组,比如weacher这个index中,可以按照城市分组,比如 北京 上海

注意事项: 不建议使用type 因为按照elastic search的计划后面的版本7.0以后会移除type

Field

我们就可以。理解为每个document字段,这个和jpa的column有点类似

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface Field {

	FieldType type() default FieldType.Auto;

	boolean index() default true;

	DateFormat format() default DateFormat.none;

	String pattern() default "";

	boolean store() default false;

	boolean fielddata() default false;

	String searchAnalyzer() default "";

	String analyzer() default "";

	String[] ignoreFields() default {};

	boolean includeInParent() default false;
}

需要了解的几个地方

  • type

返回值是FieldType 类型

public enum FieldType {
	text, Integer, Long, Date, Float, Double, Boolean, Object, Auto, Nested, Ip, Attachment, keyword
}

可以理解为数据类型

扫描二维码关注公众号,回复: 1455617 查看本文章
  • analyzer 指定分词器

  • searchAnalyzer 查询时候使用的分词器

上面的代码自动会去判断是否存在index,不存在创建

通过上面的代码创建的index如下:

{
    "resource": {
        "aliases": {},
        "mappings": {
            "resources": {
                "properties": {
                    "content": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    },
                    "createTime": {
                        "type": "long"
                    },
                    "id": {
                        "type": "long"
                    },
                    "name": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    },
                    "publishTime": {
                        "type": "long"
                    },
                    "url": {
                        "type": "text",
                        "fields": {
                            "keyword": {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "writer": {
                        "type": "text",
                        "analyzer": "ik_max_word"
                    }
                }
            }
        },
        "settings": {
            "index": {
                "refresh_interval": "1s",
                "number_of_shards": "5",
                "provided_name": "resource",
                "creation_date": "1524469358634",
                "store": {
                    "type": "fs"
                },
                "number_of_replicas": "1",
                "uuid": "Q43LJHzkRJW5_kJtpumI-g",
                "version": {
                    "created": "6010299"
                }
            }
        }
    }
}

使用

ElasticsearchRepository

熟悉spring data 这个project的朋友,应该会比较熟悉,简单说就是spring data 项目帮忙做了一些封装,只要继承相关的repository就可以做一些增删改查的操作了

首先我们继承ElasticsearchRepository这个接口,绑定相关的实体类和id类型

public interface ResourceRepository extends ElasticsearchRepository<Resource,Long>{

}

数据插入

 @Test
    public void contextLoads() {
        long count = resourceService.resourcesCount();
        System.out.println("总数:" + count);

        long start = System.currentTimeMillis();
        //查询数据,插入到elastic search
        int pages = (int) (count / 200);
        int page = 1;

        while (page < pages) {
            PageInfo<Resource> resources = resourceService.resources(1, 200);
            page++;
            List<Resource> list = resources.getList();
            resourceRepository.saveAll(list);
        }
        long end = System.currentTimeMillis();

        System.out.println("执行结束:" + (end - start));
    }

上面的代码是将数据库中查询到的数据插入到elastic search 中

数据查询

@Test
    public void search() {
        long start = System.currentTimeMillis();
        resourceRepository.findById(200L);
        long end = System.currentTimeMillis();
        System.out.println("elastic 查询时间:" + (end - start));
        start = System.currentTimeMillis();
        resourceService.findResourceById(200L);
        end = System.currentTimeMillis();
        System.out.println("mysql 查询时间:" + (end - start));

    }

上面的代码是两种实现,一种从数据库中查询,一种从elastic search中查询

elastic 查询时间:123
mysql 查询时间:297

我MySQL数据库中只有三千多条数据,从执行结果来看,elastic search的查询效率更高,可以考虑用来作为缓存使用

数据全文检索

@Test
    public void searchContent(){
        Iterable<Resource> search = resourceRepository.search(new MatchQueryBuilder("content", "心怡"));
        search.forEach(resource -> {
            System.out.println(resource.getName());
            System.out.println(resource.getContent());
        });
    }

全文检索含有'心怡'关键字

项目源码

我把项目的代码传到码云了,大家可以参考具体的代码

https://gitee.com/kipeng928829/springboot-elasticsearch

猜你喜欢

转载自my.oschina.net/kipeng/blog/1799827