mongo 使用 ID 列表进行数据库查找并计算某个字段并将其添加到原始文档中

mongo db lookup with list of IDs and count a certain field and add it to the original document

我有两个不同的collection。以下是 -

Collection A(其中包含管道ID列表):

    {
        "_id" : "1c0c97b6-8313-4ed2-8fd3-abbb82fe5e72",
        "minToClose" : 1,
        
        "pipelines" : ["c6ce1f81-b109-4f70-a9b7-53322c1b1a93","f9a0eb75-b56e-4819-a836-e5ae9abb43cd","b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa" ],
        "extra" : {
            "autoPair" : "2022-06-02T09:36:15.317Z"
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z"),
    },{
        "_id" : "26965615-979b-49dc-99ef-47be25c2d4c2",
        "minToClose" : 3,
        "pipelines" : ["c6ce1f81-b109-4f70-a9b7-53322c1b1a93","f9a0eb75-b56e-4819-a836-e5ae9abb43cd", "50d577ec-d4bc-4417-8d9c-db1d4795d29b","264f4f2c-baff-443f-82dc-cc462aa67bd6","b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"   ],
        "extra" : {
            "autoPair" : "2022-06-02T09:36:15.317Z"
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z"),
    }

现在我们有管道 collection :

    {
    "_id" : "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
    "status" : "OPEN",
    "isAbandoned" : false,
    "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
    "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
     },{
    "_id" : "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
    "status" : "CLOSE",
    "isAbandoned" : false,
    "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
    "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
     },
{
    "_id" : "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa",
    "status" : "CLOSE",
    "isAbandoned" : false,
    "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
    "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
     },{
    "_id" : "50d577ec-d4bc-4417-8d9c-db1d4795d29b",
    "status" : "CANCEL",
    "isAbandoned" : false,
    "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
    "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
     },{
    "_id" : "264f4f2c-baff-443f-82dc-cc462aa67bd6",
    "status" : "OPEN",
    "isAbandoned" : false,
    "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
    "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
     }

我想统计Close+cancel的次数,放在collectionA的extra map中。像下面的代码:

{
        "_id" : "1c0c97b6-8313-4ed2-8fd3-abbb82fe5e72",
        "minToClose" : 1,
        
        "pipelines" : ["c6ce1f81-b109-4f70-a9b7-53322c1b1a93","f9a0eb75-b56e-4819-a836-e5ae9abb43cd","b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa" ],
        "extra" : {
            "autoPair" : "2022-06-02T09:36:15.317Z",
            "totalClosedandCanceledCount" :  2
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z"),
    },{
        "_id" : "26965615-979b-49dc-99ef-47be25c2d4c2",
        "minToClose" : 3,
        "pipelines" : ["c6ce1f81-b109-4f70-a9b7-53322c1b1a93","f9a0eb75-b56e-4819-a836-e5ae9abb43cd", "50d577ec-d4bc-4417-8d9c-db1d4795d29b","264f4f2c-baff-443f-82dc-cc462aa67bd6","b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"   ],
        "extra" : {
            "autoPair" : "2022-06-02T09:36:15.317Z",
            "totalClosedandCanceledCount" :  3
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z"),
    }

我尝试编写 mongo 聚合。但未能迭代 list.Any 帮助?

这是满足您聚合需求的尝试...

聚合

db.a.aggregate([
    { $addFields: { pipelinesOriginal: "$pipelines" } }, 
    { $unwind: "$pipelines" },
    {
        $lookup:
        {
            from: "pipeline",
            localField: "pipelines",
            foreignField: "_id",
            as: "lookupValues"
        }
    },
    {
        $unwind: "$lookupValues"
    },
    {
        $match: { "lookupValues.status": { $in: [ "CLOSE", "CANCEL" ] } }
    },
    {
        $group:
        {
            _id: "$_id",
            minToClose: { $first: "$minToClose" },
            pipelines: { $first: "$pipelinesOriginal" },
            extra: { $first: "$extra" },
            createdAt: { $first: "$createdAt" },
            updatedAt: { $first: "$updatedAt" },
            count: { $sum: 1}            
        }
    },
    { $addFields: { "extra.totalClosedandCanceledCount": { "$toInt": "$count" } } },
    { $project: { "count": 0 } }
]).pretty()

结果

{
        "_id" : "26965615-979b-49dc-99ef-47be25c2d4c2",
        "minToClose" : 3,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "50d577ec-d4bc-4417-8d9c-db1d4795d29b",
                "264f4f2c-baff-443f-82dc-cc462aa67bd6",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z",
                "totalClosedandCanceledCount" : 3
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
}
{
        "_id" : "1c0c97b6-8313-4ed2-8fd3-abbb82fe5e72",
        "minToClose" : 1,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z",
                "totalClosedandCanceledCount" : 2
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
}

说明

阶段 1 - { $addFields: { pipelinesOriginal: "$pipelines" } }

需要保留最终输出的管道键值数组。阶段 2 将根据需要修改文档值以进行解析...

第 2 阶段 -{ $unwind: "$pipelines" }

第三阶段需要单独记录的外键。出于这个原因,使用 $unwind.

将它们分开

阶段 3 - { $lookup: { from: "pipeline", localField: "pipelines", foreignField: "_id", as: "lookupValues" } }

从相关 table/collection 获取详细信息。这会将找到的结果放入每个名为 lookupValues.

的相关文档中的数组中

第 4 阶段 -{ $unwind: "$lookupValues" }

对于第 6 阶段的分组和聚合函数,我们需要为每个找到的查找记录创建一条记录。因此,展开数组 lookupValues.

中找到的值

阶段 5 - { $match: { "lookupValues.status": { $in: [ "CLOSE", "CANCEL" ] } } }

只考虑 CLOSECANCEL 的状态值进行计数。

第 6 阶段 - $group(没有将整个运算符放在这里 - 太长)

基本上,按原始_id 字段值分组并统计阶段5 中匹配的每条记录。使用$first 运算符保留其他字段。请注意,我们将原始管道数组以其原始形式放回此处。

第 7 阶段 -{ $addFields: { "extra.totalClosedandCanceledCount": "$count" } }

将计数移动到文档的所需区域。在这里,我们在现有字段 extra.

下创建并嵌入一个新字段 totalClosedandCanceledCount

第 8 阶段 -{ $project: { "count": 0 } }

使用投影删除字段 count。我们已经将该字段复制到 extra.totalClosedandCanceledCount 中的所需位置,我们不再需要该字段 count.

结论

没有排序谓词,也没有指定排序。

附录

测试数据

db.a.insertMany([{
        "_id" : "1c0c97b6-8313-4ed2-8fd3-abbb82fe5e72",
        "minToClose" : 1,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z"
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
},
{
        "_id" : "26965615-979b-49dc-99ef-47be25c2d4c2",
        "minToClose" : 3,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "50d577ec-d4bc-4417-8d9c-db1d4795d29b",
                "264f4f2c-baff-443f-82dc-cc462aa67bd6",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z"
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
}])


db.pipeline.insertMany([{
        "_id" : "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
        "status" : "OPEN",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
        "status" : "CLOSE",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa",
        "status" : "CLOSE",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "50d577ec-d4bc-4417-8d9c-db1d4795d29b",
        "status" : "CANCEL",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "264f4f2c-baff-443f-82dc-cc462aa67bd6",
        "status" : "OPEN",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
}])

编辑

根据要求说明,集合 'a' 中没有相关记录被关闭或取消的记录计数必须为零。

测试记录

db.a.drop();
db.a.insertMany([{
        "_id" : "1c0c97b6-8313-4ed2-8fd3-abbb82fe5e72",
        "minToClose" : 1,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z"
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
},
{
        "_id" : "26965615-979b-49dc-99ef-47be25c2d4c2",
        "minToClose" : 3,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "50d577ec-d4bc-4417-8d9c-db1d4795d29b",
                "264f4f2c-baff-443f-82dc-cc462aa67bd6",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z"
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
},
{
        "_id" : "d5c54949-93b1-4a38-a2ed-067803448b8d",
        "minToClose" : 1,
        "pipelines" : [
                "b1cad01b-b1c7-46d5-8eef-00fe4c3eb68b",
                "a22d0ba6-8494-437d-ac4e-d470be850684",
                "bf10be9d-3214-4c64-9bc9-5e9d4beea746"
        ],
        "extra" : {
                "autoPair" : "2022-06-01T09:36:15.317Z"
        },
        "createdAt" : ISODate("2022-06-01T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-01T09:36:15.266Z")
}])








db.pipeline.drop()
db.pipeline.insertMany([{
        "_id" : "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
        "status" : "OPEN",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
        "status" : "CLOSE",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa",
        "status" : "CLOSE",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "50d577ec-d4bc-4417-8d9c-db1d4795d29b",
        "status" : "CANCEL",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "264f4f2c-baff-443f-82dc-cc462aa67bd6",
        "status" : "OPEN",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "b1cad01b-b1c7-46d5-8eef-00fe4c3eb68b",
        "status" : "OPEN",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "a22d0ba6-8494-437d-ac4e-d470be850684",
        "status" : "OPEN",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
},
{
        "_id" : "bf10be9d-3214-4c64-9bc9-5e9d4beea746",
        "status" : "OPEN",
        "isAbandoned" : false,
        "createdAt" : ISODate("2022-05-27T16:13:22.160Z"),
        "updatedAt" : ISODate("2022-05-27T16:13:45.779Z")
}])

聚合

db.a.aggregate([
    { $addFields: { pipelinesOriginal: "$pipelines" } }, 
    { $unwind: "$pipelines" },
    {
        $lookup:
        {
            from: "pipeline",
            localField: "pipelines",
            foreignField: "_id",
            as: "lookupValues"
        }
    },
    { $unwind: "$lookupValues" },
    {
        $project:
        {
            _id: 1,
            minToClose: 1,
            pipelines: "$pipelinesOriginal",
            extra: 1,
            createdAt: 1,
            updatedAt: 1,
            lookupValues: 1,
            closedFlag:
            {
                $switch:
                {
                    branches:
                    [
                        { "case": { $eq: [ "$lookupValues.status", "CLOSE" ] }, then: 1 },
                        { "case": { $eq: [ "$lookupValues.status", "CANCEL" ] }, then: 1 }
                    ],
                    default: 0
                }
            }
        }
    },
    {
        $group:
        {
            _id: "$_id",
            minToClose: { $first: "$minToClose" },
            pipelines: { $first: "$pipelines" },
            extra: { $first: "$extra" },
            createdAt: { $first: "$createdAt" },
            updatedAt: { $first: "$updatedAt" },
            count: { $sum: "$closedFlag"} 
        }
    },
    { $addFields: { "extra.totalClosedandCanceledCount": { "$toInt": "$count" } } },
    { $project: { "count": 0 } }
]).pretty()

结果

{
        "_id" : "d5c54949-93b1-4a38-a2ed-067803448b8d",
        "minToClose" : 1,
        "pipelines" : [
                "b1cad01b-b1c7-46d5-8eef-00fe4c3eb68b",
                "a22d0ba6-8494-437d-ac4e-d470be850684",
                "bf10be9d-3214-4c64-9bc9-5e9d4beea746"
        ],
        "extra" : {
                "autoPair" : "2022-06-01T09:36:15.317Z",
                "totalClosedandCanceledCount" : 0
        },
        "createdAt" : ISODate("2022-06-01T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-01T09:36:15.266Z")
}
{
        "_id" : "26965615-979b-49dc-99ef-47be25c2d4c2",
        "minToClose" : 3,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "50d577ec-d4bc-4417-8d9c-db1d4795d29b",
                "264f4f2c-baff-443f-82dc-cc462aa67bd6",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z",
                "totalClosedandCanceledCount" : 3
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
}
{
        "_id" : "1c0c97b6-8313-4ed2-8fd3-abbb82fe5e72",
        "minToClose" : 1,
        "pipelines" : [
                "c6ce1f81-b109-4f70-a9b7-53322c1b1a93",
                "f9a0eb75-b56e-4819-a836-e5ae9abb43cd",
                "b0c5d1dd-6af0-40d0-a0c9-0e659d62b0fa"
        ],
        "extra" : {
                "autoPair" : "2022-06-02T09:36:15.317Z",
                "totalClosedandCanceledCount" : 2
        },
        "createdAt" : ISODate("2022-06-02T09:36:15.266Z"),
        "updatedAt" : ISODate("2022-06-02T09:36:15.266Z")
}