赞
踩
场景: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条数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。