Mongo按单个枚举和其他字段排序

时间:2019-06-12 10:02:22

标签: mongodb

在我的收藏中,我有以下字段:

{
  ...
  status: ['scheduled', 'sent', 'error']
  sendDate: Date()
}

我的目标是首先显示scheduled,然后显示按error排序的sent{ sendDate: -1 }。我会进行2次查询,但我想让它分页。由于时区不同,sendDate可能会以scheduled的形式出现在其他sent之前。喜欢:

{
  id: 1,
  sendDate: ISODate("2019-06-11T19:28:50.617Z"),
  status: 'scheduled'
}, {
  id: 2,
  sendDate: ISODate("2019-06-12T19:28:50.617Z"),
  status: 'sent'
}, {
  id: 3,
  sendDate: ISODate("2019-06-10T19:28:50.617Z"),
  status: 'scheduled'
}, {
  id: 4,
  sendDate: ISODate("2019-06-10T19:28:50.617Z"),
  status: 'sent'
}, {
  id: 5,
  sendDate: ISODate("2019-06-11T19:28:50.617Z"),
  status: 'error'
}

预期的排序ID为:

{
  id: 1,
  status: 'scheduled'
},{ 
  id: 3,
  status: 'scheduled'
},{ 
  id: 2,
  status: 'sent'
},{ 
  id: 5,
  status: 'error'
},{ 
  id: 4,
  status: 'sent'
}

2 个答案:

答案 0 :(得分:4)

您可以在运行时通过添加一个字段(优先级)并根据优先级和DateTime进行排序来完成此操作;

db.collectionName.aggregate([
    {"$addFields" : {
        "priority" :  {"$cond": { if: { $eq: [ "$status", "scheduled" ] }, then: 2, else: 1 }}
        }
    },
    {"$sort" : {"priority" : -1, "sendDate" : -1}}
])

尽管对于非常大(数百万个记录)的馆藏不是一个很好的解决方案 运行例如。 https://mongoplayground.net/p/0oEZyOyUCCH

答案 1 :(得分:0)

无法进行这种排序。

在每个文档中添加一个priority字段,使您能够进行排序。

预定的priority比其他的多。然后在此字段上排序。

例如,在此状态下,将0 scheduled1的优先级赋予其他任何优先级。通过在Ascending字段上对priority进行排序,可以实现所需的功能。当然,通过为每种类型的文档添加不同的优先级,您可以处理订购过程。 (例如,预定时间:0,发送时间:1,错误:2)

使用这种方法,您可以将priority添加到应比其他文件更快处理的任何类型的文档中。它不依赖于文档状态,因此,如果将来添加任何其他状态,则可以轻松处理。

因此您的文档应如下所示:

{
  id: 1,
  sendDate: ISODate("2019-06-11T19:28:50.617Z"),
  status: 'scheduled',
  priority: 0
}, {
  id: 2,
  sendDate: ISODate("2019-06-12T19:28:50.617Z"),
  status: 'sent',
  priority: 1
}, {
  id: 3,
  sendDate: ISODate("2019-06-10T19:28:50.617Z"),
  status: 'scheduled',
  priority: 1
}, {
  id: 4,
  sendDate: ISODate("2019-06-10T19:28:50.617Z"),
  status: 'sent',
  priority: 1
}, {
  id: 5,
  sendDate: ISODate("2019-06-11T19:28:50.617Z"),
  status: 'error',
  priority: 1
}

和您的订单:

{
  "priority": 1,
  "sendDate": -1
}