文档章节

spring-data-elasticsearch

后海
 后海
发布于 2019/03/15 16:21
字数 3108
阅读 1.3K
收藏 4

spring-data-elasticsearch

@Document

  • @Document(indexName = "es",type = "user",shards = 5,replicas = 0) : 标注在实体类上,声明存储的索引和类型
    • indexName: 索引名称
    • type:索引类型
    • shards:分片的数量
    • replicas:副本的数量
    • refreshInterval: 刷新间隔
    • indexStoreType:索引文件存储类型

@Field

  • 标注在属性上,用来指定属性的类型。其中的属性如下:
    • analyzer:指定分词器,es中默认使用的标准分词器,比如我们需要指定中文IK分词器,可以指定值为ik_max_word
    • type: 指定该属性在es中的类型,其中的值是FileType类型的值,比如FileType.Text类型对应es中的text类型
    • index:指定该词是否需要索引,默认为true
    • store:指定该属性内容是否需要存储,默认为
    • fielddata :指定该属性能否进行排序,因为es中的text类型是不能进行排序(已经分词了)
    • searchAnalyzer : 指定搜索使用的分词器
  • 在插入数据之前我们需要先运行程序添加mapping,对于没有指定@Field的属性此时是不会创建索引的,而是在插入数据的时候自动创建索引。但是对于@Field注解标注的属性如果没有先加载生成mapping,等到插入数据的时候是没有效果的
  • 如果使用该注解,那么必须指定其中的type属性

@Id

  • 主键注解,标识一个属性为主键

Date类型的存储

  • es中默认存储Date类型的是一个时间戳,如果我们需要指定格式的存储,那么需要在@Field这个注解中指定日期的格式。如下:
 

1

2

3

 

@Field(type = FieldType.Date,format = DateFormat.custom, pattern ="yyyy-MM-dd HH:mm:ss")

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

private Date birthday;

创建一个实体类

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

 

/**

* @Document : 这个是ES的注解,在类使用,指定实体类的索引和类型。默认所有的属性都是索引的

* 1、indexName : 指定索引

* 2、type:指定类型

* 3、shards:指定分片的数量

* 4、replicas:指定副本的数量

*/

@Document(indexName = "es",type = "user",shards = 5,replicas = 0)

public class User {

@Id //指定这个是主键

private Integer userId;

@Field(type = FieldType.Text,analyzer = "ik_max_word",fielddata = true,store = false)

private String userName;

private String password;

@Field(type = FieldType.Date, store = true, format = DateFormat.custom, pattern ="yyyy-MM-dd HH:mm:ss")

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

private Date birthday;

private List<String> hobbies;

public Integer getUserId() {

return userId;

}

public void setUserId(Integer userId) {

this.userId = userId;

}

public String getUserName() {

return userName;

}

public void setUserName(String userName) {

this.userName = userName;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

public List<String> getHobbies() {

return hobbies;

}

public void setHobbies(List<String> hobbies) {

this.hobbies = hobbies;

}

@Override

public String toString() {

return "User{" +

"userId=" + userId +

", userName='" + userName + '\'' +

", password='" + password + '\'' +

", birthday=" + birthday +

", hobbies=" + hobbies +

'}';

}

}

定义查询接口

  • 官网上提供了各种各样的方法,我们使用继承ElasticsearchRepository这个接口的方式拓展查询接口,基本的接口:
 

1

2

3

 

public interface UserRepo extends ElasticsearchRepository<User,Integer> {

//不需要实现其中的方法,只需要继承即可,spring-data-es会为我们自动完成

}

常用方法如下:

  1. index(T t) :添加数据
  2. save(T t):添加数据
  3. count(): 获取数据总数
  4. findAll():获取所有的数据,返回的是一个java.lang.Iterable
  5. Iterable<T> findAllById(Iterable<ID> ids):根据Id批量返回数据
  6. saveAll(Iterable entity) :批量保存数据,可以传入List
  7. delete(T t) : 删除指定的实体类,只需要指定实体类中的Id即可
  8. deleteAll():删除所有的数据
  9. deleteById(ID Id):根据Id删除数据
  10. existsById(ID Id): 判断指定Id的数据是否存在
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

 

//添加数据

@Test

public void test3(){

User user=new User();

user.setUserId(1);

user.setUserName("郑元梅");

user.setBirthday(new Date());

user.setPassword("12345678");

List<String> hobbies=new ArrayList<>();

hobbies.add("篮球");

hobbies.add("足球");

user.setHobbies(hobbies);

// userRepo.save(user); //调用其中的save方法保存信息

userRepo.index(user); //调用index方法添加数据

}

//获取其中的所有数据

@Test

public void test4(){

Iterable<User> iterable=userRepo.findAll();

Iterator<User> iterator=iterable.iterator();

while (iterator.hasNext()){

System.out.println(iterator.next());

}

}

@Test

public void test5(){

List<User> users=new ArrayList<>();

User user=new User();

user.setUserId(4);

user.setUserName("张三");

user.setBirthday(new Date());

user.setPassword("12345678");

List<String> hobbies=new ArrayList<>();

hobbies.add("台球");

hobbies.add("足球");

user.setHobbies(hobbies);

User user1=new User();

user1.setUserId(5);

user1.setUserName("郑元梅");

user1.setBirthday(new Date());

user1.setPassword("12345678");

user1.setHobbies(hobbies);

users.add(user);

users.add(user1);

userRepo.saveAll(users); //保存List中的所有数据

}

//删除指定的数据

@Test

public void test6(){

User user=new User();

user.setUserId(5);

userRepo.delete(user);

}

@Test

public void test7(){

List<User> users=userRepo.selectAll();

for (User user

:users

) {

System.out.println(user);

}

}

自定义查询

  • spring-data-elasticsearch为我们自动完成了许多的查询,我们只需要按照其中的规范使用即可。
    • 查询方法定义以get或者find开头即可
  • 关于es中各种查询,我们可以参照下表进行定义,文档
And findByNameAndPrice {"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
Or findByNameOrPrice {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
Is findByName {"bool" : {"must" : {"field" : {"name" : "?"}}}}
Not findByNameNot {"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
Between findByPriceBetween {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqual findByPriceLessThan {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
GreaterThanEqual(>=) findByPriceGreaterThan {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
Before(<=) findByPriceBefore {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
After findByPriceAfter {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
Like?%)(如果需要实现%?%可以使用fuzzy) findByNameLike {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWith findByNameStartingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWith findByNameEndingWith {"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/Containing findByNameContaining {"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}
In findByNameIn(Collection<String>names) {"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotIn findByNameNotIn(Collection<String>names) {"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
Near findByStoreNear Not Supported Yet !
True findByAvailableTrue {"bool" : {"must" : {"field" : {"available" : true}}}}
False findByAvailableFalse {"bool" : {"must" : {"field" : {"available" : false}}}}
OrderBy findByAvailableTrueOrderByNameDesc {"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}}

实例

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

 

package com.techwells.es;

import com.techwells.beans.User;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.Pageable;

import org.springframework.data.elasticsearch.annotations.Document;

import org.springframework.data.elasticsearch.annotations.Query;

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.Date;

import java.util.List;

public interface UserRepo extends ElasticsearchRepository<User,Integer>{

/**

* 根据userId获取用户信息

* @param userId

* @return

*/

User findUserByUserId(Integer userId);

/**

* 根据用户查找用户信息

* @param userName

* @return

*/

List<User> findByUserName(String userName);

/**

* 根据用户名和密码查找用户信息,使用的是must查询

* 参数的顺序不能颠倒

* @param userName

* @param password

* @return

*/

List<User> findByUserNameAndPassword(String userName,String password);

/**

* 根据用户名或者地址进行查询,满足其一即可,使用的是should

* 参数不能颠倒

* @param userName

* @param address

* @return

*/

List<User> findByUserNameOrAddress(String userName,String address);

/**

* 使用@Query注解自定义查询语句,其中的?是占位符,0表示第一个参数

* @param userName

* @return

*/

@Query("{\n" +

" \"bool\": {\n" +

" \"must\": [\n" +

" {\n" +

" \"match\": {\n" +

" \"userName\": \"?0\"\n" +

" }\n" +

" }\n" +

" ]\n" +

" }\n" +

" }")

List<User> selectByUserName(String userName);

/**

* 查询密码不为null的用户信息

* @return

*/

@Query("{\n" +

" \"bool\": {\n" +

" \"must\":{\n" +

" \"exists\":{\n" +

" \"field\":\"password\"\n" +

" }\n" +

" }\n" +

" }\n" +

" }")

List<User> findByPasswordIsNotNull();

/**

* 查询密码为null的用户信息

* @return

*/

@Query("{\n" +

" \"bool\": {\n" +

" \"must_not\":{\n" +

" \"exists\":{\n" +

" \"field\":\"password\"\n" +

" }\n" +

" }\n" +

" }\n" +

" }")

List<User> findByPasswordIsNull();

/**

* 查询密码不是password的用户信息,使用的must_not

* @param password

* @return

*/

List<User> findByPasswordNot(String password);

/**

* 查询用户名是userName但是密码表示password的信息,必须同时满足

* @param userName

* @param password

* @return

*/

List<User> findByUserNameAndPasswordNot(String userName,String password);

/**

* 查询年龄在from-to之间的用户,包含form和to,使用的是range查询

* @param from 起始

* @param to 截止

* @return

*/

List<User> findByAgeBetween(Integer from,Integer to);

/**

* 查询年龄小于age的用户信息

* @param age 年龄

* @return

*/

List<User> findByAgeLessThan(Integer age);

/**

* 年龄小于等于age的用户信息

*/

List<User> findByAgeLessThanEqual(Integer age);

/**

* 年龄大于age的用户

* @param age

* @return

*/

List<User> findByAgeGreaterThan(Integer age);

/**

* 年龄大于等于age的用户

* @param age

* @return

*/

List<User> findByAgeGreaterThanEqual(Integer age);

/**

* 年龄小于等于age的用户信息

* @param age

* @return

*/

List<User> findByAgeBefore(Integer age);

/**

* 年龄大于等于age的用户

* @param age

* @return

*/

List<User> findByAgeAfter(Integer age);

/**

* 模糊查找,密码中以pwd开头用户信息,`content%`,

* @param content

* @return

*/

List<User> findByPasswordLike(String content);

/**

* 查询密码中包含content的用户信息 %content%

* @param content

* @return

*/

List<User> findByPasswordContaining(String content);

/**

* 查询密码以pwd开头的用户信息,和Like一样的效果

* @param pwd

* @return

*/

List<User> findByPasswordStartingWith(String pwd);

/**

* 查询密码以pwd结尾的用户信息

* @param pwd

* @return

*/

List<User> findByPasswordEndingWith(String pwd);

/**

* 查找年龄在集合中的用户信息

* @param ages

* @return

*/

List<User> findByAgeIn(List<Integer> ages);

/**

* 查找年龄不在集合中的用户信息

* @param ages

* @return

*/

List<User> findByAgeNotIn(List<Integer> ages);

/**

* 根据用户名查询并且按照年龄降序排列

* @param userName

* @return

*/

List<User> findByUserNameOrderByAgeDesc(String userName);

/**

* 根据用户名查询并且按照年龄降序排列、用户名升序排列

* @param userName

* @return

*/

List<User> findByUserNameOrderByAgeDescUserNameAsc(String userName);

/**

* 根据出生日期进行降序排列

* @param userName

* @return

*/

List<User> findByUserNameOrderByBirthdayDesc(String userName);

/**

* 返回前2条数据

* @param userName

* @return

*/

List<User> findTop2ByUserName(String userName);

/**

* 根据用户名分页查询

* @param userName

* @param pageable

* @return

*/

Page<User> findByUserName(String userName, Pageable pageable);

}

使用@Query定义自己的es语句

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

 

/**

* 使用@Query注解自定义查询语句,其中的?是占位符,0表示第一个参数

* @param userName

* @return

*/

@Query("{\n" +

" \"bool\": {\n" +

" \"must\": [\n" +

" {\n" +

" \"match\": {\n" +

" \"userName\": \"?0\"\n" +

" }\n" +

" }\n" +

" ]\n" +

" }\n" +

" }")

List<User> selectByUserName(String userName);

控制结果集数量

 

1

2

3

4

5

6

 

/**

* 返回前2条数据

* @param userName

* @return

*/

List<User> findTop2ByUserName(String userName);

分页查询

  • https://www.tianmaying.com/tutorial/spring-jpa-page-sort
  • 直接使用org.springframework.data.domain.Pageable进行分页排序即可
    • page:从0开始,第几页,默认为0
    • size:每页显示的数量
    • sort:排序的方向
  • 其中的方法如下:
    • getTotalElements():返回数据的总数,不是分页的总数,而是根据条件查询到的全部的数据的总数
    • getContent():获取分页的数据集合List<T>
    • getTotalPages():获取总共几页的数据
    • iterator():获取迭代器
    • 剩余的方法如下:
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

 

public interface Slice<T> extends Streamable<T> {

//返回当前是第几页

int getNumber();

//返回每页显示的数量

int getSize();

//返回当前页获取到的元素数量

int getNumberOfElements();

//返回当前页元素的集合

List<T> getContent();

//判断当前页是否存在数据

boolean hasContent();

//获取排序的Sort

Sort getSort();

//判断当前页是否是第一页

boolean isFirst();

//判断当前页是否是最后一页

boolean isLast();

//判断是否还有下一页

boolean hasNext();

//判断是否有前一页

boolean hasPrevious();

//返回当前页的pageable

default Pageable getPageable() {

return PageRequest.of(getNumber(), getSize(), getSort());

}

//返回下一页的Pageable

Pageable nextPageable();

//返回前一页的pageable

Pageable previousPageable();

<U> Slice<U> map(Function<? super T, ? extends U> converter);

}

单条件分页排序

  • 只使用了一个字段进行排序
 

1

2

3

4

5

6

7

8

9

10

 

@Test

public void test3(){

Sort sort=new Sort(Sort.Direction.DESC,"age");

Pageable pageable=new PageRequest(9,1,sort);

Page<User> users=userRepo.findByUserName("李",pageable);

System.out.println(users.getTotalPages());

for (User user:users.getContent()) {

System.out.println(user);

}

}

多条件分页排序

  • 使用Order进行排序条件
 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

@Test

public void test3(){

List<Sort.Order> orders=new ArrayList<>();

orders.add(new Sort.Order(Sort.Direction.DESC,"age"));//按照年龄降序排列

orders.add(new Sort.Order(Sort.Direction.ASC,"userId")); //按照用户Id升序排列

Sort sort=new Sort(orders); //使用orders

Pageable pageable=new PageRequest(0,10,sort);

Page<User> users=userRepo.findByUserName("李",pageable);

System.out.println(users.getTotalPages());

for (User user:users.getContent()) {

System.out.println(user);

}

}

本文转载自:https://chenjiabing666.github.io/2018/09/02/spring-data-elasticsearch/

后海

后海

粉丝 33
博文 48
码字总数 25623
作品 2
闵行
后端工程师
私信 提问
spring-data-elasticsearch 基本案例详解(三)

『 风云说:能分享自己职位的知识的领导是个好领导。 』 运行环境:JDK 7 或 8,Maven 3.0+ 技术栈:SpringBoot 1.5+, Spring Data Elasticsearch 1.5+ ,ElasticSearch 2.3.2 本文提纲 一、...

夜黑人模糊灬
2018/05/13
1.3K
1
ElasticSearch开发问题汇总(不断更新中)

1、Mapping: [译]ElasticSearch数据类型--string类型已死, 字符串数据永生 ElasticSearch动态日期映射 2、Spring Data Elasticsearch: Spring Data Elasticsearch教程...

九州暮云
2018/07/18
298
0
【ElasticSearch】---SpringBoot整合ElasticSearch

SpringBoot整合ElasticSearch 一、基于spring-boot-starter-data-elasticsearch整合 开发环境:springboot版本:2.0.1,elasticSearch-5.6.8.jar版本:5.6.8,服务器部署ElasticSearch版本:......

雨点的名字
2018/08/23
0
0
聊聊springboot elasticsearch autoconfigure

序 本文主要研究一下springboot elasticsearch autoconfigure ElasticsearchAutoConfiguration spring-boot-autoconfigure-2.1.4.RELEASE-sources.jar!/org/springframework/boot/autoconfi......

go4it
2019/04/17
106
0
elasticsearch入门到放弃之spring boot elasticsearch x-pack

spring-boot-data-elasticsearch 代码地址:https://github.com/zhaoyunxing92/spring-boot-learn-box/tree/master/spring-boot-elasticsearch/spring-boot-data-elasticsearch 这个就跟我在......

zhaoyunxing
2019/07/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

六、Spring Cloud之配置中心config

前言 前面我们讲了微服务的注册中心、负载均衡、熔断处理、网管服务。接下来我们讲配置中心,为什么要用配置中心呢? 其实我们接触一段时间就可以发现,我们的项目还是非常多的,每个项目都有...

quellanan2
8分钟前
19
0
在Android的EditText视图中允许多行?

如何在Android的EditText视图中允许多行? #1楼 这对我有用 ,实际上这两个属性很重要: inputType和lines 。 此外,您可能需要一个滚动条,下面的代码显示了如何制作一个: <EditText ...

技术盛宴
12分钟前
13
0
分享自己写的JS版日期格式化和解析工具类,绝对好用!

前言 本来想模仿Java里面的SimpleDateFormat()对象的,但是感觉这样用起来不方便,所以还是直接写成单独的方法算了。 原文链接 日期格式化 2.1. 使用说明 formatDate(date, fmt),其中fmt支持...

SuShine
21分钟前
27
0
快递鸟api物流查询接口实现订阅物流轨迹单号查询功能对接调用

背景: 分享一篇关于在电商系统中同步物流轨迹到本地服务器的文章,当前方案使用了快递鸟集成api做为数据来源接口,这个接口是免费使用的,不过提供的功能还是非常强大的,有专门的售后维护团...

程序的小猿
26分钟前
24
0
Day08多态,abstract,接口

1.A:多态的概述:事物存在的多种形态。 B:多态前提:要有继承关系,方法重写和父类引用子类对象。 父类引用子类对象:Animal a = new Cat(); a.eat(); //效果等同于c.eat(); 2.多态中的...

Lao鹰
32分钟前
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部