如何在 MongoDB 中使用嵌套分组
How to use nested grouping in MongoDB
我需要查找每个组织级别的重复配置文件总数。我有如下所示的文件:
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "75"
}
"_id" : "1"
},
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "75"
}
"_id" : "2"
},
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "77"
}
"_id" : "3"
},
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "77"
}
"_id" : "4"
}
我写了一个查询,它是一个由 ProfileId 和 OrganizationId 组成的组。我得到的结果如下所示:
Organization Total
10 2
10 2
但我想获得每个组织级别的总和,这意味着 Org 10 应该有一行总和为 4。
我正在使用的查询如下所示:
db.getSiblingDB("dbName").OrgProfile.aggregate(
{ $project: { _id: 1, P: "$Profile._id", O: "$OrganizationId" } },
{ $group: {_id: { p: "$P", o: "$O"}, c: { $sum: 1 }} },
{ $match: { c: { $gt: 1 } } });
有什么想法吗?请帮助
我想我有一个解决方案。在最后一步,我想你想要另一个 $group
.
而不是匹配
.aggregate([
{ $project: { _id: 1, P: "$Profile._id", O: "$OrganizationId" } }
,{ $group: {_id: { p: "$P", o: "$O"}, c: { $sum: 1 }} }
,{ $group: { _id: "$_id.o" , c: { $sum: "$c" } }}
]);
您可能可以阅读它并自己弄清楚最后一步发生了什么,但为了以防万一,我会解释一下。最后一步是将具有相同组织 ID 的所有文档分组,然后将前一个 c
字段指定的数量相加。在第一组之后,您有两个文档,它们的计数 c
均为 2,但配置文件 ID 不同。下一组忽略配置文件 ID,如果他们具有相同的组织 ID 并添加他们的计数,则将它们分组。
当我 运行 这个查询时,这是我的结果,这就是我认为你正在寻找的:
{
"_id" : 10,
"c" : 4
}
希望这对您有所帮助。如果您有任何问题,请告诉我。
下面的管道应该给你想要的输出,而最后的 $project
阶段只是为了装饰目的,将 _id
变成 OrganizationId
但不是基本计算所必需的所以你可以省略它。
db.getCollection('yourCollection').aggregate([
{
$group: {
_id: { org: "$OrganizationId", profile: "$Profile._id" },
count: { $sum: 1 }
}
},
{
$group: {
_id: "$_id.org",
Total: {
$sum: {
$cond: {
if: { $gte: ["$count", 2] },
then: "$count",
else: 0
}
}
}
}
},
{
$project: {
_id: 0,
Organization: "$_id",
Total: 1
}
}
])
给出这个输出
{
"Total" : 4.0,
"Organization" : 10
}
要过滤掉没有重复的组织,您可以使用 $match
这也会导致第二个 $group
阶段的简化
...aggregate([
{
$group: {
_id: { org: "$OrganizationId", profile: "$Profile._id" },
count: { $sum: 1 }
}
},
{
$match: {
count: { $gte: 2 }
}
},
{
$group: {
_id: "$_id.org",
Total: { $sum: "$count" }
}
},
{
$project: {
_id: 0,
Organization: "$_id",
Total: 1
}
}
])
我需要查找每个组织级别的重复配置文件总数。我有如下所示的文件:
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "75"
}
"_id" : "1"
},
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "75"
}
"_id" : "2"
},
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "77"
}
"_id" : "3"
},
{
"OrganizationId" : 10,
"Profile" : {
"_id" : "77"
}
"_id" : "4"
}
我写了一个查询,它是一个由 ProfileId 和 OrganizationId 组成的组。我得到的结果如下所示:
Organization Total
10 2
10 2
但我想获得每个组织级别的总和,这意味着 Org 10 应该有一行总和为 4。
我正在使用的查询如下所示:
db.getSiblingDB("dbName").OrgProfile.aggregate(
{ $project: { _id: 1, P: "$Profile._id", O: "$OrganizationId" } },
{ $group: {_id: { p: "$P", o: "$O"}, c: { $sum: 1 }} },
{ $match: { c: { $gt: 1 } } });
有什么想法吗?请帮助
我想我有一个解决方案。在最后一步,我想你想要另一个 $group
.
.aggregate([
{ $project: { _id: 1, P: "$Profile._id", O: "$OrganizationId" } }
,{ $group: {_id: { p: "$P", o: "$O"}, c: { $sum: 1 }} }
,{ $group: { _id: "$_id.o" , c: { $sum: "$c" } }}
]);
您可能可以阅读它并自己弄清楚最后一步发生了什么,但为了以防万一,我会解释一下。最后一步是将具有相同组织 ID 的所有文档分组,然后将前一个 c
字段指定的数量相加。在第一组之后,您有两个文档,它们的计数 c
均为 2,但配置文件 ID 不同。下一组忽略配置文件 ID,如果他们具有相同的组织 ID 并添加他们的计数,则将它们分组。
当我 运行 这个查询时,这是我的结果,这就是我认为你正在寻找的:
{
"_id" : 10,
"c" : 4
}
希望这对您有所帮助。如果您有任何问题,请告诉我。
下面的管道应该给你想要的输出,而最后的 $project
阶段只是为了装饰目的,将 _id
变成 OrganizationId
但不是基本计算所必需的所以你可以省略它。
db.getCollection('yourCollection').aggregate([
{
$group: {
_id: { org: "$OrganizationId", profile: "$Profile._id" },
count: { $sum: 1 }
}
},
{
$group: {
_id: "$_id.org",
Total: {
$sum: {
$cond: {
if: { $gte: ["$count", 2] },
then: "$count",
else: 0
}
}
}
}
},
{
$project: {
_id: 0,
Organization: "$_id",
Total: 1
}
}
])
给出这个输出
{
"Total" : 4.0,
"Organization" : 10
}
要过滤掉没有重复的组织,您可以使用 $match
这也会导致第二个 $group
阶段的简化
...aggregate([
{
$group: {
_id: { org: "$OrganizationId", profile: "$Profile._id" },
count: { $sum: 1 }
}
},
{
$match: {
count: { $gte: 2 }
}
},
{
$group: {
_id: "$_id.org",
Total: { $sum: "$count" }
}
},
{
$project: {
_id: 0,
Organization: "$_id",
Total: 1
}
}
])