MongoDb索引
注解索引
Springboot JPA 默认不开启自动创建索引,需在yml配置开启,并且只在【新创建的集合】才会生效。
1 2 3 4
| spring: data: mongodb: auto-index-creation: true
|
标注字段,在创建数据库的时候,会自动创建索引。
1 2
| @Indexed(unique = true, direction = IndexDirection.DESCENDING) private String username;
|
组合索引,在创建数据库的时候,会自动创建索引。
1 2 3 4 5 6 7
| @CompoundIndexes({ @CompoundIndex(name = "username_age", def = "{'username': 1, 'age': 1}", unique = true) }) public class User{ private String username; private int age; }
|
shell添加索引
如果集合里已经有数据了,建议手动增加索引
1 2 3 4 5 6 7 8 9 10
| $ mongo > use test switched to db test > > # 给test集合的username字段创建索引,并且唯一。(1代表升序 -1代表降序) > db.test.createIndex({ username: 1 }, { unique: true }) >
> db.test.createIndex({ username: 1 , age: 1 })
|
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
| @Test void findUserList(){ User user = new User(); user.setName("zhangsan"); user.setAge(20); Example<User> userExample = Example.of(user); List<User> users = userRepository.findAll(userExample); System.out.println(users); }
@Test void findLikeUserList(){ ExampleMatcher matcher = ExampleMatcher.matching() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING) .withIgnoreCase(true); User user = new User(); user.setName("z"); Example<User> userExample = Example.of(user,matcher); List<User> users = userRepository.findAll(userExample); System.out.println(users); }
@Test void findPageUserList(){ Pageable pageable = PageRequest.of(0, 3); User user = new User(); user.setName("zhangsan"); Example<User> userExample = Example.of(user); Page<User> page = userRepository.findAll(userExample, pageable); System.out.println(page); }
|
下面是支持的查询类型,每三条数据分别对应:(方法后缀,方法例子,mongodb原生查询语句)
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
| GreaterThan(大于) findByAgeGreaterThan(int age) {"age" : {"$gt" : age}}
LessThan(小于) findByAgeLessThan(int age) {"age" : {"$lt" : age}}
Between(在...之间) findByAgeBetween(int from, int to) {"age" : {"$gt" : from, "$lt" : to}}
IsNotNull, NotNull(是否非空) findByFirstnameNotNull() {"age" : {"$ne" : null}}
IsNull, Null(是否为空) findByFirstnameNull() {"age" : null}
Like(模糊查询) findByFirstnameLike(String name) {"age" : age} ( age as regex)
(No keyword) findByFirstname(String name) {"age" : name}
Not(不包含) findByFirstnameNot(String name) {"age" : {"$ne" : name}}
Near(查询地理位置相近的) findByLocationNear(Point point) {"location" : {"$near" : [x,y]}}
Within(在地理位置范围内的) findByLocationWithin(Circle circle) {"location" : {"$within" : {"$center" : [ [x, y], distance]}}}
Within(在地理位置范围内的) findByLocationWithin(Box box) {"location" : {"$within" : {"$box" : [ [x1, y1], x2, y2]}}}
|
尽管以上查询功能已经很丰富,但如果还不能满足使用情况的话可以用一下方法—基于mongodb原本查询语句的查询方式。
例:在原接口中加入
1 2
| @Query("{ 'name':{'$regex':?2,'$options':'i'}, sales': {'$gte':?1,'$lte':?2}}") public Page<Product> findByNameAndAgeRange(String name,double ageFrom,double ageTo,Pageable page);
|
注释Query里面的就是mongodb原来的查询语法,我们可以定义传进来的查询参数,通过坐标定义方法的参数。
还可以在后面指定要返回的数据字段,如上面的例子修改如下,则只通过person表里面的name和age字段构建person对象。
1 2
| @Query(value="{ 'name':{'$regex':?2,'$options':'i'}, sales':{'$gte':?1,'$lte':?2}}",fields="{ 'name' : 1, 'age' : 1}") public Page<Product> findByNameAndAgeRange(String name,double ageFrom,double ageTo,Pageable page);
|