首页 > 解决方案 > 从嵌套对象数组排序 MongoDB - NodeJS

问题描述

希望你一切都好,祝大家新年快乐。希望它最终会比 2020 X 更好)。我在这里面临一个问题,到目前为止我找不到解决方案。这是一个数据 MongoDB 模型示例:

`{ "_id" : ObjectId("5fe715bf43c3ca0009503f1d"), 
"firstname" : "Nicolas ",
"lastname" : "Mazzoleni",
"email" : "nicolas.mazzoleni@orange.fr",
"items" : [ 
    {
        "item" : ObjectId("5f6c5422eeaa1364b0d7b267"),
        "createdAt" : "2020-12-26T10:51:43.685Z"
    }, 
    {
        "item" : ObjectId("5f6c5422eeaa1364b0d7b270"),
        "createdAt" : "2021-01-04T09:21:46.260Z"
    }
],
"createdAt" : ISODate("2020-12-26T10:51:43.686Z"),
"updatedAt" : ISODate("2021-01-04T09:21:46.260Z"),
"__v" : 0
}`

假设我有很多像上面这样的行,具有不同的“items.createdAt”日期。

最后,目标是执行一个查询,找到一个 ObjectId 等于我要查找的项目,并按匹配的“items.createdAt”日期排序。这是我目前使用的查询,它没有按匹配的嵌套对象排序:

  `const items = await repo
  .find({ 'items.item': ObjectId("5f6c5422eeaa1364b0d7b270") })
  .sort({ 'items.createdAt': -1 })
  .limit(5)`

PS:我还尝试使用以该查询结尾的聚合

  `const items = await repo.aggregate([
  { $unwind: '$items' },
  { $match: { 'items.item': ObjectId("5f6c5422eeaa1364b0d7b270") } },
  { $sort: { 'items.createdAt': -1 } },
  { $limit: 5 },
])`

这个工作就像一个魅力,但它不使用索引,我正在搜索数百万条记录,这使得这种查询方式执行时间很长。

谢谢你的帮助 !尼古拉斯

标签: node.jsmongodbmongoose

解决方案


不幸的是,MongoDB 无法通过简单的 Query 对嵌套数组进行排序。您需要为此使用聚合。


db.collection.aggregate([
  {
    "$match": {
      "items.item": ObjectId("5f6c5422eeaa1364b0d7b270")
    }
  },
  {
    "$unwind": "$items"
  },
  {
    "$sort": {
        "items.createdAt": -1
     }
  },
  { "$limit" : 5 },
  {
    "$group": {
        "items": {
            "$push": "$items"
        },
        "_id": 1
  }
])

推荐阅读