spring mongodb分頁,動態條件、字段查詢

使用MongRepository

public interface VideoRepository extends MongoRepository<Video, String> {
    Video findVideoById(String id);
    // 視頻分頁預覽{title,coverImg}
    Page<Video> findByGradeAndCourse(Grade grade, Course course, Pageable page);
}
  • 問題
    • 動態條件查詢?
    • 只查詢指定字段?
  1. 指定字段
@Query(fields = "{'title':1, 'coverImg':1, 'course':1}")
Page<Video> findBy(Criteria where, Pageable page);
  1. 指定條件
DBObject obj = new BasicDBObject();
obj.put("userId", new BasicDBObject("$gte", 2));

BasicDBObject fieldsObject = new BasicDBObject();
fieldsObject.put("userId", 1);
fieldsObject.put("name", 1);

Query query = new BasicQuery(obj.toString(), fieldsObject.toString());
  • demo,使用MongoTemplate,Query,DBObject
@Override
    public Result getVideos(Pageable page, Long gradeId, Long courseId) {
        DBObject obj = new BasicDBObject();
        if(gradeId!=null&&gradeId!=0){
            obj.put("grade.id", gradeId);
        }
        if(gradeId!=null&&gradeId!=0){
            obj.put("course.id", courseId);
        }
        obj.put("course.id", 2);
//        obj.put("course.id", new BasicDBObject("$gte", 2));

        BasicDBObject fieldsObject = new BasicDBObject();
        fieldsObject.put("title", 1);
        fieldsObject.put("coverImg", 1);
        fieldsObject.put("course", 1);
        Query query = new BasicQuery(obj.toString(), fieldsObject.toString());
        query.skip(page.getOffset()).limit(page.getPageSize());
        List<Video> videos = mongoTemplate.find(query, Video.class);
        // 總個數
        long count = mongoTemplate.count(query, Video.class);
        Page<Video> result = new PageImpl<Video>(videos, page, count);
        return Result.success(videos);
    }

查詢條件對於屬性是對象(course)沒法生效,該方法仍是不可行java

混合 (終極法器)

本質上仍是使用MongoTemplate來實現的,MongoRepository能實現查詢指定字段,可是不能實現動態條件查詢。ide

MongoTemplate的find方法接收Query參數,Query能夠實現動態字段,可是動態條件不是普適應的(我還沒找到),對於對象屬性沒法查詢。可是Query有一個addCriteria方法,該方法能夠將Example融合到Query中。所以find方法使用了Example的動態查詢,Query的動態字段查詢。spa

  • VidoeOperations
public interface VideoOperations {
    Page<Video> findAllPage(Example<Video> example, DBObject fields, Pageable page);
}
  • VideoRepository
public interface VideoRepository extends MongoRepository<Video, String>, VideoOperations {
    Video findVideoById(String id);
}
  • VideoRepositoryImpl
public class VideoRepositoryImpl implements VideoOperations {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Override
    public Page<Video> findAllPage(Example<Video> example, DBObject fields, Pageable page) {
        Query query = new BasicQuery(null, fields.toString());
        query.addCriteria((new Criteria()).alike(example));
        query.with(page);
//        Query q = (new Query((new Criteria()).alike(example))).with(page);
        List<Video> list = mongoTemplate.find(query, example.getProbeType());
        return PageableExecutionUtils.getPage(list, page, () -> {
            return mongoTemplate.count(query, example.getProbeType());
        });
    }
}
Keyword Sample Logical result
After findByBirthdateAfter(Date date) {"birthdate" : {"$gt" : date}}
GreaterThan findByAgeGreaterThan(int age) {"age" : {"$gt" : age}}
GreaterThanEqual findByAgeGreaterThanEqual(int age) {"age" : {"$gte" : age}}
Before findByBirthdateBefore(Date date) {"birthdate" : {"$lt" : date}}
LessThan findByAgeLessThan(int age) {"age" : {"$lt" : age}}
LessThanEqual findByAgeLessThanEqual(int age) {"age" : {"$lte" : age}}
Between findByAgeBetween(int from, int to) {"age" : {"$gt" : from, "$lt" : to}}
In findByAgeIn(Collection ages) {"age" : {"$in" : [ages…]}}
NotIn findByAgeNotIn(Collection ages) {"age" : {"$nin" : [ages…]}}
IsNotNull, NotNull findByFirstnameNotNull() {"firstname" : {"$ne" : null}}
IsNull, Null findByFirstnameNull() {"firstname" : null}
Like, StartingWith, EndingWith findByFirstnameLike(String name) {"firstname" : name} (name as regex)
NotLike, IsNotLike findByFirstnameNotLike(String name) {"firstname" : { "$not" : name }} (name as regex)
Containing on String findByFirstnameContaining(String name) {"firstname" : name} (name as regex)
NotContaining on String findByFirstnameNotContaining(String name) {"firstname" : { "$not" : name}} (name as regex)
Containing on Collection findByAddressesContaining(Address address) {"addresses" : { "$in" : address}}
NotContaining on Collection findByAddressesNotContaining(Address address) {"addresses" : { "$not" : { "$in" : address}}}
Regex findByFirstnameRegex(String firstname) {"firstname" : {"$regex" : firstname }}
(No keyword) findByFirstname(String name) {"firstname" : name}
Not findByFirstnameNot(String name) {"firstname" : {"$ne" : name}}
Near findByLocationNear(Point point) {"location" : {"$near" : [x,y]}}
Near findByLocationNear(Point point, Distance max) {"location" : {"$near" : [x,y], "$maxDistance" : max}}
Near findByLocationNear(Point point, Distance min, Distance max) {"location" : {"$near" : [x,y], "$minDistance" : min, "$maxDistance" : max}}
Within findByLocationWithin(Circle circle) {"location" : {"$geoWithin" : {"$center" : [ [x, y], distance]}}}
Within findByLocationWithin(Box box) {"location" : {"$geoWithin" : {"$box" : [ [x1, y1], x2, y2]}}}
IsTrue, True findByActiveIsTrue() {"active" : true}
IsFalse, False findByActiveIsFalse() {"active" : false}
Exists findByLocationExists(boolean exists) {"location" : {"$exists" : exists }}
相關文章
相關標籤/搜索