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" ] } } }
只考虑 CLOSE
或 CANCEL
的状态值进行计数。
第 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")
}
我有两个不同的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" ] } } }
只考虑 CLOSE
或 CANCEL
的状态值进行计数。
第 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")
}