首页 > 解决方案 > Mongodb - 在子文档中组合数组然后排序

问题描述

我有一个名为“作者”的文档,其中包含一个名称和一系列书籍。

我想将所有“书籍”字段(它们是子文档的数组)加入一个数组中。然后我需要根据“页面”字段过滤掉一些子文档(我已经这样做了)。

然后,我想根据子文档中的“已发布”字段对该数组进行排序。

这是我的文件

{
    "_id": ObjectId(5f67b448c869aa0de8cdb449),
    "name":"Author 1",
    "books":[
        {
            "_id": ObjectId(5f67b448c869aa0de8cdb44a),
            "title": "Book 1",
            "pages": 59,
            "released": "2019-09-21T19:58:00.795+00:00"
        },
        {
            "_id": ObjectId(5f67b448c869aa0de8cdb44b),
            "title": "Book 2",
            "pages": 21,
            "released": "2019-03-05T20:58:00.798+00:00"
        }
    ]
}
{
    "_id": ObjectId(5f67b448c869aa0de8cdb44c),
    "name":"Author 2",
    "books":[
        {
            "_id": ("5f67b448c869aa0de8cdb44d),
            "title": "Book 3",
            "pages": 75,
            "released": "2020-03-04T20:58:00.802+00:00"
        },
        {
            "_id": ObjectId(5f67b448c869aa0de8cdb44e),
            "title": "Book 4",
            "pages": 49,
            "released": "2019-08-17T19:58:00.802+00:00"
        }
    ]
}

我曾尝试使用此聚合,它允许我过滤掉少于 21 页的书籍。

[
    {
        $project: {
            books: {
                $filter: {
                    input: '$books',
                    as: 'book',
                    cond: {
                        $gt: ['$$book.pages', 21]
                    }
                }
            }
        }
    }
]

这是我的结果。

[
    {
        _id: 5f67b448c869aa0de8cdb449,
        books: [
            {
                "_id": ObjectId(5f67b448c869aa0de8cdb44a),
                "title": "Book 1",
                "pages": 59,
                "released": "2019-09-21T19:58:00.795+00:00"
            }
        ]
    },
    {
        _id: 5f67b448c869aa0de8cdb44c,
        books: [
            {
                "_id": ("5f67b448c869aa0de8cdb44d),
                "title": "Book 3",
                "pages": 75,
                "released": "2020-03-04T20:58:00.802+00:00"
            },
            {
                "_id": ObjectId(5f67b448c869aa0de8cdb44e),
                "title": "Book 4",
                "pages": 49,
                "released": "2019-08-17T19:58:00.802+00:00"
            }
        ]
    }
]

我正在寻找这样格式的结果。(通过过滤器的所有书籍的数组,也已排序。)

books: [
    {
        "_id": ObjectId(5f67b448c869aa0de8cdb44e),
        "title": "Book 4",
        "pages": 49,
        "released": "2019-08-17T19:58:00.802+00:00"
    },
    {
        "_id": ObjectId(5f67b448c869aa0de8cdb44a),
        "title": "Book 1",
        "pages": 59,
        "released": "2019-09-21T19:58:00.795+00:00"
    },
    {
        "_id": ("5f67b448c869aa0de8cdb44d),
        "title": "Book 3",
        "pages": 75,
        "released": "2020-03-04T20:58:00.802+00:00"
    }
]

标签: mongodbaggregation-frameworkaggregation

解决方案


您可以使用$unwind扁平化数组,然后$match根据您的条件获取匹配的对象。然后用于$sort根据发布日期排序并重新组合使用$group

[
  {
    $unwind: "$books"
  },
  {
    $match: {
      "books.pages": {
        $gt: 21
      }
    }
  },
  {
    $sort: {
      "books.released": 1
    }
  },
  {
    $group: {
      _id: null,
      "books": {
        $push: "$books"
      }
    }
  }
]

工作Mongo游乐场


推荐阅读