Mongo - Java - 将所有文档排序字符串日期作为日期

Posted

技术标签:

【中文标题】Mongo - Java - 将所有文档排序字符串日期作为日期【英文标题】:Mongo - Java - get all documents sort string date as date 【发布时间】:2020-04-13 01:58:48 【问题描述】:

只是想知道最好的方法是什么。以下代码需要能够将字符串日期作为日期值按降序排序,但需要分页。

documentList = collection.find().skip(skip).limit(limit).sort(Sorts.descending("ReceivedDate"));

除了排序不工作之外,其余的工作都是一种享受。我仍然习惯使用 Mongo。认为最好找出做事的正确方法或好方法。尽早养成好习惯。

我发现的链接的不同之处在于我在分页中添加了。

我查看了一些链接,但不是 100% 确定我在使用 find 时需要什么。 Sort by date string (ascending) on Mongo MongoDB sorting date string (mm/dd/yyyy)

我们尝试使用降序分页的典型文档是


"_id" : ObjectId("5ddc80b3adbe1d0001bc50f7"),
"ReceivedDate" : "20/12/2019",
"ReceivedTime" : "08:00:00",
"batch_id" : "112233",
"EventMessage" : "SUCCESS",
"Observations" : 1,
"DataSet" : "xxxx",
"SetType" : "yyy",
"SetName" : "yyyxxx",

提前非常感谢, 罗素

【问题讨论】:

您可以考虑在排序之前使用聚合来适当地格式化日期。 我不明白为什么我不能按从字符串转换为日期的键进行排序。我来自 T-SQL 背景,您可以更轻松地完成这类事情。类似于以下内容,但语法几乎可以肯定是错误的。 documentList = collection.find().skip(skip).limit(limit).sort(Sorts.descending(date: $dateFromString: dateString: '$date' )); 我发布了针对您的问题的解决方案的答案。我怀疑(并且不认为)您可以在光标的 sort 方法中使用 $expr 。该解决方案使用聚合,我已经为此发布了Java代码。 【参考方案1】:

以下代码需要能够将字符串日期排序为日期 值按降序排列,但有分页。

documentList = collection.find().skip(skip).limit(limit).sort(Sorts.descending("ReceivedDate"));

除了排序不工作之外,其余的工作都是一种享受。

您必须使用“YYYY-MM-DD”(字符串格式)格式的ReceivedDate(字符串格式)才能对其进行排序,使用 date 字段包含字符串中的值。

这样做的方法是使用聚合;例如:

带有日期字符串的文档: _id: 1, dt : "20/12/2019" ,可以转换为Date进行排序:

db.test.aggregate( [
 
  $project:  
      dt:  
         $dateFromString:  dateString: "$dt", format: "%d/%m/%Y"  
      
  
,
] )

结果: "_id" : 1, "dt" : ISODate("2019-12-20T00:00:00Z")

并且,查询的其余部分可以是聚合查询,其功能与您现在使用的 find 查询相同。下面的代码解决了这个问题。

解决方案:

您的查询:

documentList = collection.find().skip(skip).limit(limit).sort(Sorts.descending("ReceivedDate"));

Mongo Shell中的聚合中转换为以下内容:

db.test.aggregate( [
 
  $project:  
      dt:  
         $dateFromString:  dateString: "$dt", format: "%d/%m/%Y"  
      
  
,
 $sort:  dt : -1  ,
 $skip: 2 ,
 $limit: 1 
] )

并且,在 Java 中:

Bson addFields = addFields(new Field<Document>("dt", 
                                               new Document("$dateFromString", 
                                                            new Document("dateString", "$dt")
                                                                .append("format", "%d/%m/%Y")
                                                            )
));

List<Bson> pipeline = Arrays.asList(addFields, sort(descending("dt")), skip(2), limit(1));
List<Document> results = new ArrayList<>();
collection.aggregate(pipeline).into(results);

// The required MongoDB driver imports:
import org.bson.Document;
import org.bson.conversions.Bson;
import static com.mongodb.client.model.Aggregates.addFields;
import static com.mongodb.client.model.Aggregates.limit;
import static com.mongodb.client.model.Aggregates.skip;
import static com.mongodb.client.model.Aggregates.sort;
import static com.mongodb.client.model.Sorts.descending;
import com.mongodb.client.model.Field;

参考资料:

Aggregation Optimization using $sort + $skip + $limit Sequence。 $expr 用法。

【讨论】:

感谢您澄清我提到的 sort() 函数和 T-SQL 角度。欣赏更完整的响应,尤其是示例 java 代码。【参考方案2】:

设法花一些时间,所以我想我会分享更完整的答案。这当然是唯一可能的,因为这个问题得到了帮助。谢谢大家。

使用 Robo 3T 和 javascript 样式,我设法找到了我需要的更完整的答案。

db.getCollection('API_LOG').aggregate([
 
  $project:  
      dt:  
         $dateFromString:  dateString: "$ReceivedDate", format: "%d/%m/%Y"  
      ,
      ReceivedTime : 1,
      batch_id : 1,
      EventMessage : 1,
      ExpectedObservations:1,
      DataSetProvider:1,
      DataSetType:1,
      DataSetName:1,
  
,
 $sort:  dt : -1  ,
 $skip: 0 ,
 $limit: 100 
] )

然后上面的示例 java 代码非常适合获取列表,然后我可以使用它来访问相关数据。

感谢您的帮助。

【讨论】:

以上是关于Mongo - Java - 将所有文档排序字符串日期作为日期的主要内容,如果未能解决你的问题,请参考以下文章

用于组的 mongo 排序子文档

为啥聚合+排序比mongo中的查找+排序更快?

mongo学习-固定集合

为啥 Mongoose ORM 选择不使用常规的 mongo 语法进行查找、排序等?

将所有数组元素的ISO日期转换为mongo 3.4(而不是3.6)中的等效JSON文档

将索引与 Mongo 的 $first 组运算符一起使用