Java MongoTemplate 查询时限制内嵌集合返回的数据量

场景:MongoDB表中的某字段数据量非常大,需要限制只返回该字段 【最新】 的2000条数据

数据结构:datas字段中的数据,根据时间排序如下,最新的数据排在文档的最底下

{ 
    ...
    "userid" : "123", 
    "datas" : [
        {
            "id" : "111", 
            "time" : ISODate("2019-05-20T08:12:13.058+0000")
        }, 
        {
            "id" : "222", 
            "time" : ISODate("2019-05-21T02:49:57.090+0000")
        }, 
        {
            "id" : "333", 
            "time" : ISODate("2019-05-22T07:19:13.022+0000")
        },
        ...
    ], 
    ...
}

前提:

Java MongoTemplate查询返回【内嵌集合】指定数量的数据,核心代码:

详情查看:https://blog.csdn.net/weixin_41888813/article/details/96995155

问题:以下代码可以获取到datas集合中【0,2000】的数据,从旧数据开始截取,并不是最新数据

// one 标记
MongoCollection<Document> collection =
    mongoClient.getDatabase(YOUR_DATABASE_NAME).getCollection(YOUR_COLLECTION_NAME);

// two 标记
FindIterable<Document> findIterable = collection.find()
        .filter(eq("userid", userid))
        .projection(fields(include("datas"), excludeId(), slice("datas", 2000)));

// three 标记
Document resultDocument = findIterable.first();
if (document != null) {
    entity = Tools.json2Object(Tools.bulidJSON(resultDocument), Entity.class);
}

 

思路一:查询中加入嵌套集合内容排序,改动 two 标记处的代码:嵌套文档无法进行排序,行不通

详情查看:https://blog.csdn.net/weixin_41888813/article/details/97117784

// two
FindIterable<Document> findIterable = collection.find()
        .filter(eq("userid", userid))
//      .sort(Sorts.descending("datas.createtime"))
//      .sort(Sorts.orderBy(Sorts.descending("datas.createtime")))
//      .sort(new Document("datas.createtime", -1))
        .projection(fields(include("datas"), excludeId(), slice("datas", 2000)));

 

思路二:使用unwind拆分集合再聚合拼装,性能消耗问题,行不通

//            Aggregation agg = newAggregation(
//                    unwind("datas"),
//                    project("userid", userid)
//            );
//            AggregationResults<Document> result = mongoTemplate.aggregate(agg, Document.class);
//            Document document = result.getMappedResults().get(0);

 

思路三:发现 two 标记处的 【slice()】可传入跳过元素数,那么需要先获取出datas字段的长度

skip  @param limit the number of elements to project 应用此限制之前要跳过的元素数

    /**
     * Creates a projection to the given field name of a slice of the array value of that field.
     *
     * @param fieldName the field name
     * @param skip the number of elements to skip before applying the limit
     * @param limit the number of elements to project 应用此限制之前要跳过的元素数
     * @return the projection
     * @mongodb.driver.manual reference/operator/projection/slice Slice
     */
    public static Bson slice(final String fieldName, final int skip, final int limit) {
        return new BsonDocument(fieldName, new BsonDocument("$slice", new BsonArray(asList(new BsonInt32(skip), new BsonInt32(limit)))));
    }

 

第一步:获取出datas字段的长度

法一详情:https://blog.csdn.net/weixin_41888813/article/details/97149494

spring-data-mongodb 包需要 2.1.1.RELEASE的版本,但项目底层用了旧版封装MongoDB代码,引入新依赖,底层代码报错

    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-mongodb</artifactId>
      <version>2.1.1.RELEASE</version>
    </dependency>

法二详情:https://blog.csdn.net/weixin_41888813/article/details/97114714

获取到内嵌的集合的数据大小后,传入到 two 标记的第二个参数中,加入处理,实现查询出最新的2000条数据

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值