我如何排序mongodb最后排序的空值?

Tob*_*Seo 6 mongodb

我在mongo shell中执行此查询

db.getCollection('list').find({}).sort({next_time: 1})
Run Code Online (Sandbox Code Playgroud)

结果是

next_time
--
null
null
null
2015-02-21 00:00:00
2015-03-25 00:00:00
2015-08-29 00:00:00
Run Code Online (Sandbox Code Playgroud)

我希望得到这样的结果

next_time
--
2015-02-21 01:00:00
2015-03-25 01:00:00
2015-08-29 01:00:00
null
null
null
Run Code Online (Sandbox Code Playgroud)

不同的是'null'是最后在列表中排序的.我怎么能这样做?

Buz*_*tti 6

也许您可以使用聚合和人为的高结束日期:

c = db.foo.aggregate([
{$project: {
            next_time: 1,
            nlt: { $ifNull: [ "$next_time", new ISODate("9000-01-01") ] }
  }     
}
,
{$sort: { "nlt": 1}}
                  ]);
c.forEach(function(r) { printjson(r); });
Run Code Online (Sandbox Code Playgroud)

或者,如果大多数材料都有空,而您根本不想处理这些文档,那么将它们过滤掉,只剩$sort下剩下的:

db.foo.aggregate([
{$match: {"nt": {$exists: true}}}
,
{$sort: { "nt": 1}}
                 ]);
Run Code Online (Sandbox Code Playgroud)

  • 但是,所有空值都分配了错误的“9000-01-01”值,需要将其恢复。这感觉非常错误,我认为对于巨大的投影(限制很小)来说它也非常慢。非常不幸的是,MongoDB 不支持某些 sql 语言中的“order by X nulls last”之类的功能。/我相信这是jira上的相关问题:https://jira.mongodb.org/browse/SERVER-24310 (6认同)

Fer*_*nch 6

如果您可以向文档添加字段,则可以添加一个“反向”字段,当您按降序排序时,该字段会按升序返回您的文档。

只是为了澄清:mongo 将 null 值视为“最小”值,因此它们在按升序排序时首先出现,在按降序排序时最后出现。

所以,如果你的元素是这样的:

{
  ...
  next_time: ISODate("2020-05-01")
}
Run Code Online (Sandbox Code Playgroud)

既然ISODate("2020-05-01").getTime()1588291200000,您可以添加:

{
  ...
  next_time: ISODate("2020-05-01"),
  next_time_inverted: -1588291200000
}
Run Code Online (Sandbox Code Playgroud)

然后将反转后的值按降序排序:

db.getCollection('list').find({}).sort({next_time_inverted: -1})
Run Code Online (Sandbox Code Playgroud)

必要时不要忘记在该字段上添加索引。