【问题标题】:mongoDB, mongoose - aggregation an array of objectsmongoDB, mongoose - 聚合对象数组
【发布时间】:2021-06-06 13:48:35
【问题描述】:

我有 3 个要汇总的集合。

第一个是colors系列

{
    {
        _id: 1,   <- mongoose objectId
        name: red
    },
    {
        _id: 2,   <- mongoose objectId
        name: green
    }
}

第二个是产品

{
    {
        _id: Id777, <- mongoose objectId
        productName: test prod 777
    },
    {
        _id: Id888, <- mongoose objectId
        productName: test prod 888
    }
}

第三个移动收藏

{
    ....other fields here
    items: [
        {
            _id: an mongoose id,
            itemId: Id777 <- in products collection,
            itemColor: 1 <- id in colors collection,
            coutn: 7,
            ....other fields
        },
        {
            _id: an mongoose id,
            itemId: Id888 <- in products collection,
            itemColor: 2 <- id in colors collection
            cout: 10
            ....other fields
        }
    ]
}

我需要这样的输出:

{
    ////information from collection
    items: [
        {
            itemId: test prod 777, itemColor: red, count: 7
        },
        {
            itemId: test prod 888, itemColor: green, count: 10
        }
    ]
}

我的代码是:

      const moves = await ProductMoves.aggregate([
            { $match: query }, // this is my query

            {
                $lookup: {
                    from: 'products',
                    localField: 'items.itemId',
                    foreignField: '_id',
                    as: 'productName'
                }
            },
            {
                $unwind: { path: "$productName" , preserveNullAndEmptyArrays: true }
            },

            {
                $lookup: {
                    from: 'colors',
                    localField: 'items.itemColor',
                    foreignField: '_id',
                    as: 'cName'
                }
            },
            {
                $unwind: { path: "$cName" , preserveNullAndEmptyArrays: true }
            },

            {
                $addFields: {
                    mItems: {
                        prName: "$productName.productName",
                        prColor: "$cName.colorName"
                    },
                    productName: 0,
                    cName: 0
                }
            }

        ])
            .sort({addedDate: -1})
            .skip(+req.query.offset)
            .limit(+req.query.limit)

但它只返回对象数组中的 1 个元素。可能我需要类似 for 循环的东西,但我做不到。

感谢您的回复,祝您有美好的一天!

【问题讨论】:

    标签: mongodb mongoose aggregation-framework


    【解决方案1】:
    • $unwind解构items数组
    • $lookupproducts 合集
    • $lookupcolors 收藏
    • $addFields, $arrayElemAt 从查找结果中获取第一个元素
    • $group by _id 并重构 items 数组并传递其他字段
    • 聚合函数中没有外部方法,您必须使用阶段进行排序、跳过和限制,如下所示
    • $sort addedDate 按降序排列
    • $skip$limit 结果
    const moves = await ProductMoves.aggregate([
      { $match: query }, // this is my query
      { $unwind: "$items" },
      {
        $lookup: {
          from: "products",
          localField: "items.itemId",
          foreignField: "_id",
          as: "itemId"
        }
      },
      {
        $lookup: {
          from: "colors",
          localField: "items.itemColor",
          foreignField: "_id",
          as: "itemColor"
        }
      },
      {
        $addFields: {
          "items.itemId": { $arrayElemAt: ["$itemId.productName", 0] },
          "items.itemColor": { $arrayElemAt: ["$itemColor.name", 0] }
        }
      },
      {
        $group: {
          _id: "$_id",
          items: { $push: "$items" },
          addedDate: { $first: "$addedDate" }
          // add other fields that you want in result like "addedDate"
        }
      },
      { $sort: { addedDate: -1 } },
      { $skip: +req.query.offset },
      { $limit: +req.query.limit }
    ])
    

    Playground

    【讨论】:

      猜你喜欢
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 2020-07-27
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 2016-07-02
      相关资源
      最近更新 更多