猫鼬-仅按日期部分对日期排序,忽略时间

时间:2018-08-16 21:12:15

标签: node.js mongodb mongoose aggregation-framework

我有一个用于以下模型的收藏集:

const VisitSchema = new mongoose.Schema({
    priority: { type: Number, min: 1, max: 3, required: true },
    datetime: { type: Date, required: true },
    // some other information
});

我正在尝试对所有文档进行排序,以使较接近当前日期的访问在较晚的日期之前显示,但是在一天之内,必须首先显示优先级较高的那些。

例如:考虑

A (17-08-2018 14:00:00, P3)

B (17-08-2018 15:00:00, P2)

C (18-08-2018 15:00:00, P1)

排序时,期望的响应应该是[B, A, C],因为在17-08-2018B的优先级高于A,即使A的优先级更高即使C的优先级高于AB,也要在第二天。

我正在寻找一种方法,该方法首先按datetime进行排序,但仅考虑日期部分并忽略时间,然后按priority进行排序。我目前的尝试完全考虑了datetime,给我错误的排序方式:

Visit.find().sort('datetime priority')

编辑:我知道我可以使用Array.sort()来做到这一点。问题是直接从mongoose开始,而不是先检索数据然后才进行排序。

2 个答案:

答案 0 :(得分:5)

您可以尝试在3.6以下的汇总中进行自定义排序。

使用$dateFromParts来计算$addFields中没有时间的日期,以将计算出的值保留为文档中的多余字段,然后是$sort对字段进行排序。

$project,但要删除排序字段才能获得预期的输出。

db.col.aggregate([
 {"$addFields":{
   "date":{
     "$dateFromParts":{
       "year":{"$year":"$datetime"},
       "month":{"$month":"$datetime"},
       "day":{"$dayOfMonth":"$datetime"}
      }
    }
 }}, 
 {"$sort":{"date":-1,"priority":1}},
 {"$project":{"date":0}}
])

答案 1 :(得分:1)

您可以尝试在mongodb 3.0 及更高版本中使用$dateToString,将datetime转换为所需格式 并且可以轻松地$sort加上日期

db.collection.aggregate([
  { "$addFields": {
    "date": {
      { "$dateToString": {
        "format": "%Y-%m-%d", "date": "$datetime"
      }}
    }
  }},
  { "$sort": { "date": -1, "priority": 1 }}
])