Javascript Mongoose,对子文档数组应用`.aggregate()`并以最少的查询次数与文档的其他字段一起获得结果

Javascript Mongoose,对子文档数组应用`.aggregate()`并以最少的查询次数与文档的其他字段一起获得结果,javascript,node.js,mongodb,mongoose,aggregation-framework,Javascript,Node.js,Mongodb,Mongoose,Aggregation Framework,这是我的猫鼬模型: const postSchema = new Schema({ user: { type: Schema.Types.ObjectId, ref: 'User', required: true }, caption: { type: String }, action: { type: [{ actionName: {

这是我的猫鼬模型:

const postSchema = new Schema({
    user: {
        type: Schema.Types.ObjectId,
        ref: 'User',
        required: true
    },

    caption: {
        type: String
    },

    action: {
        type: [{
            actionName: {
                type: String,
                required: true
            },
            user: {
                type: Schema.Types.ObjectId,
                ref: 'User'
            }
        }],
        default: []
    },

    shares: [{
        type: Schema.Types.ObjectId,
        ref: 'User'
    }];
});
我所需要的是使用或不使用
.aggregate()
进行mongodb查询,以获取
用户
&
标题
字段的原样,而不是
操作
共享
,我需要特定文档的计数

示例文档

{
    _id: "fgsergehegoieofgesfglesfg",

    user: "dfjksjdnfkjsdfkjsdklfjglkbj",

    caption: "This is the post caption",

    action: [
        {
            actionName: 'e1', user: "sdfasdsdfasdfdsdfac951e5c"
        },
        {
            actionName: 'e1', user: "asdfmadfadfee103c9c951e5d"
        },
        {
            actionName: 'e2', user: "op34937cdbae0cd4160bbec"
        },
        {
            actionName: 'e2', user: "2543ebbasdfd1750690b5b01c"
        },
        {
            actionName: 'e3', user: "asdfcfebdb5dd1750690b5b01d"
        },
    ],

    shares: ["ewrebdb5ddadsf5069sadf1d", "asdfsdfbb85dd1750690b5b01c", "fasec92dsfasde103c9c95df5d"]
};
查询后的所需输出:

{
    _id: "fgsergehegoieofgesfglesfg",
    user: 'dfjksjdnfkjsdfkjsdklfjglkbj',
    caption: 'This is the post caption',
    actionCount: [{ count: 1, actionName: 'e3' },
                 { count: 2, actionName: 'e2' },
                 { count: 2, actionName: 'e1' }],
    shareCount: 3
}
使用
.aggregate()
,我可以得到以下结果:

查询:

let data = await Test.aggregate([
            { $match: { _id: mongoose.Types.ObjectId("fgsergehegoieofgesfglesfg") } },
            { $unwind: "$action" },
            {
                $group: {
                    _id: "$action.actionName",
                    count: { $sum: 1 }
                }
            },
            {
                $project: {
                    _id: 0,
                    actionName: "$_id",
                    count: 1
                }
            }
        ]);
结果:

[
  { count: 1, actionName: 'e3' },
  { count: 2, actionName: 'e2' },
  { count: 2, actionName: 'e1' } 
]
我只想把它放在原始文档中,然后得到结果。同样,对
share
字段执行相同的操作。如果这可以在单个查询中完成,那就更好了。我尝试过将
$replaceRoot
$mergeObjects
一起使用,但不知道如何正确使用它们。我对猫鼬和猫鼬很陌生


请帮忙。谢谢。

由于要聚合嵌套数组,您需要运行
$group
两次,并且
$first
可用于保留原始文档的字段值:

await Test.aggregate([
    { $match: { _id: mongoose.Types.ObjectId("fgsergehegoieofgesfglesfg") } },
    { $unwind: "$action" },
    {
        $group: {
            _id: { _id: "$_id", actionName: "$action.actionName" },
            user: { $first: "$user" },
            caption: { $first: "$caption" },
            count: { $sum: 1 },
            shareCount: { $first: { $size: "$shares" } }
        }
    },
    {
        $group: {
            _id: "$_id._id",
            user: { $first: "$user" },
            caption: { $first: "$caption" },
            shareCount: { $first: "$shareCount" },
            actionCount: {
                $push: {
                    actionName: "$_id.actionName",
                    count: "$count"
                }
            }
        }
    }
])

非常感谢。这正是我需要的。但我希望在有1000个动作的情况下使用multiple
$group
不会增加太多查询延迟。你能推荐学习mongodb的最佳方法吗?@NeetigyaChahar文档绝对是学习mongodb的最佳方法