spring-data-elasticsearch

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中各种查询,我们可以参照下表进行定义,文档
AndfindByNameAndPrice{"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
OrfindByNameOrPrice{"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}}
IsfindByName{"bool" : {"must" : {"field" : {"name" : "?"}}}}
NotfindByNameNot{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}
BetweenfindByPriceBetween{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}
LessThanEqualfindByPriceLessThan{"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}}}}}
AfterfindByPriceAfter{"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}}
Like?%)(如果需要实现%?%可以使用fuzzy)findByNameLike{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
StartingWithfindByNameStartingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}}
EndingWithfindByNameEndingWith{"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}}
Contains/ContainingfindByNameContaining{"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}}
InfindByNameIn(Collection<String>names){"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}
NotInfindByNameNotIn(Collection<String>names){"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}}
NearfindByStoreNearNot Supported Yet !
TruefindByAvailableTrue{"bool" : {"must" : {"field" : {"available" : true}}}}
FalsefindByAvailableFalse{"bool" : {"must" : {"field" : {"available" : false}}}}
OrderByfindByAvailableTrueOrderByNameDesc{"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://my.oschina.net/matol/blog/3023088

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
spring-data-elasticsearch官方教程文档提供了关于如何使用spring-data-elasticsearch框架进行Elasticsearch数据库操作的详细指导。该文档分为几个部分,包括介绍、快速入门、基本概念、查询构造器和复杂查询等。 文档的介绍部分简要介绍了spring-data-elasticsearch框架以及它提供的主要功能。快速入门部分通过一个简单的示例演示了如何配置spring-data-elasticsearch并进行基本的CRUD操作。该示例涵盖了创建索引、映射实体类、保存数据、查询数据以及删除数据。通过这个示例,读者可以迅速了解到spring-data-elasticsearch的基本用法。 基本概念部分详细介绍了spring-data-elasticsearch中的一些重要概念,包括实体类映射、索引操作、文档操作、字段映射、分页和排序等。这些概念对于深入理解spring-data-elasticsearch的使用非常重要。 查询构造器部分介绍了spring-data-elasticsearch提供的查询构造器的使用方法。该部分通过实例演示了如何使用查询构造器进行基本查询、范围查询、模糊查询以及布尔查询等。读者可以通过这些示例快速掌握查询构造器的使用。 最后一部分是关于复杂查询的介绍。这一部分介绍了如何使用原生查询、使用注解进行查询以及使用自定义实现进行查询等。复杂查询是spring-data-elasticsearch一个非常重要的特性,通过它可以实现更加灵活和高级的查询功能。 总体来说,spring-data-elasticsearch官方教程文档提供了丰富的实例和详细的说明,对于想要学习和使用spring-data-elasticsearch框架的开发者来说,是一份非常有价值的指南。读者可以通过该文档逐步了解spring-data-elasticsearch的相关概念和基本用法,并通过实例演示快速上手。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值