• 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)无法生效,该方法还是不可行

    混合 (终极法器)

    本质上还是使用MongoTemplate来实现的,MongoRepository能实现查询指定字段,但是不能实现动态条件查询。

    MongoTemplate的find方法接收Query参数,Query可以实现动态字段,但是动态条件不是普适应的(我还没找到),对于对象属性无法查询。但是Query有一个addCriteria方法,该方法可以将Example融合到Query中。因此find方法使用了Example的动态查询,Query的动态字段查询。

    • 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 }}
  • 相关阅读:
    app 后端技术
    别为大公司拼命
    ifconfig 工具
    route工具
    ping 和 traceroute 命令
    IP路由选择
    TCP的那些事儿(下)
    TCP的那些事儿(上)
    Openresty 与 Tengine
    Excel.Application SaveAs 把excel转换为html
  • 原文地址:https://www.cnblogs.com/zhuxiang1633/p/10647349.html
Copyright © 2020-2023  润新知