您的位置:首页 > 编程语言 > Java开发

SpringBoot项目通过 spring data elasticsearch使用elasticsearch

2018-04-23 16:51 801 查看

依赖添加

<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
}

可以理解为数据类型

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息