【问题标题】:Group using $group on a foreignField from another collection in mongodb使用 $group 对来自 mongodb 中另一个集合的 foreignField 进行分组
【发布时间】:2017-09-26 20:05:22
【问题描述】:

这是我的查询:

db.getCollection('_build').aggregate([
    {
        $group:{
            _id: "$ProjectId",
            Builds: {$addToSet: "$_id"}
        }
    },
    {
        $lookup:{
            from: "_build.detail",
            localField: "Builds",
            foreignField: "BuildId",
            as: "result"
        }
    },
    {
        $project:{
            _id:0,
            ProjectId: "$_id",
            Builds: 1,
            BuildCountForProject: {$size: "$Builds"}
        }
    }

]);

查询结果:

/* 1 */
{
    "Builds" : [ 
        ObjectId("58f908411f19cf1d340974c2"), 
        ObjectId("58f902bd1f19cf1d3409749d")
    ],
    "ProjectId" : ObjectId("58f7a38f1f19cf38306a1b9c"),
    "BuildCountForProject" : 11
}

/* 2 */
{
    "Builds" : [ 
        ObjectId("58f797631091c228bc3af071"), 
        ObjectId("58f79fa31091c528bc4ff8f1"), 
        ObjectId("58f769441f19cf22dc92da24"), 
        ObjectId("58f633801f19cf4f8073b203")
    ],
    "ProjectId" : ObjectId("58e27c921091c22e34243db7"),
    "BuildCountForProject" : 4
}

我在查询结果中针对每个项目获取构建数组,我想根据每个项目中的构建查询另一个集合(使用相同的查询),想要聚合一些数据(数据必须是按 ProjectId 分组,我想加入的集合中没有 ProjectId,但正如您在结果中看到的那样,我有它在管道中)。

例子:

我想为这些构建找到不同的广告、广告集、广告系列,

  1. ObjectId("58f908411f19cf1d340974c2")
  2. ObjectId("58f902bd1f19cf1d3409749d")

这两个构建都属于项目 ObjectId("58f7a38f1f19cf38306a1b9c"),如结果所示。

想要输出,

{
    "ProjetId" : ObjectId("58f7a38f1f19cf38306a1b9c"),
    "BuildId" :[ ObjectId("58f908411f19cf1d340974c2"), 
                ObjectId("58f902bd1f19cf1d3409749d")]
    "UniqueAdsCount" : 10,
    "UniqueAdsetCount": 5,
    "UniqueCampaignCount": 2 
},
{
    next ProjectId,
    Builds array,
    UniqueAdsCount
    UniqueAdsetCount
    UniqueCampaignCount
},...

我想用_build.detials 加入的收藏:

{
    "_id" : ObjectId("58de834cc6e7dbe945acf890"),
    "BuildId" : ObjectId("58ef4b95c6e7dbe945ba700b"),
    "Values" : null,
    "Headers" : null,
    "Data" : {
        "Campaign Name" : "Remarketing | Remarketing | Facebook | Conversions | 03-01-2017",
        "Ad Set Name" : "Cancelled Orders_Greater than 50%-Cancelled Orders_Less than 50% | Desktop | Feed | Female | 21-65",
        "Ad Name" : "Carousel | Draw1,Excited2,Lottery5,Beach4 | S:1814082498827964 | 03-01-2017 | 70Custom Audiences | ",
        "Ad Set Run Status" : "ACTIVE",
        "Ad Status" : "ACTIVE",
        "Campaign Objective" : "Conversions",
        "Gender" : "Female",
        "Age Min" : "21",
        "Age Max" : "65",

    },
    "Status" : false,
    "CampaignName" : "Remarketing | Remarketing | Facebook | Conversions | 03-01-2017",
    "AdSetName" : "Cancelled Orders_Greater than 50%-Cancelled Orders_Less than 50% | Desktop | Feed | Female | 21-65",
    "AdName" : "Carousel | Draw1,Excited2,Lottery5,Beach4 | S:1814082498827964 | 03-01-2017 | 70Custom Audiences | ",
    "Campaign_Status" : 1,
    "Campaign_Id" : "1",
    "Adset_Status" : 1,
    "Adset_Id" : "123",
    "Ad_Status" : 1,
    "Ad_Id" : "1234"
},...

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您可以尝试以下查询。它类似于我们这里的查询Using multiple $lookup with aggregation in mongodb

    以下查询将$lookup 转换为build details 以获取所有字段,$group 一次获取一个字段以获得不同的值,然后$project 以计算每个构建的不同值。

    最后的$group 是将所有builds 推入一个数组,同时将所有构建细节的不同计数相加。

       aggregate([
          { $group: {_id: "$ProjectId",Builds: {$addToSet: "$_id"}}},
          { $lookup: {from: "_build.detail",localField: "Builds",foreignField: "BuildId",as: "result"}},
          { $unwind: "$result"},
          {
            $group: 
             {
               _id: 
                {
                  ProjectId: "$_id",
                  BuildId: "$result.BuildId",
                  campaignName: "$result.Data.Campaign Name",
                  adSet: "$result.Data.Ad Set Name"
                },
                uniqueAdNames: {$addToSet: "$result.Data.Ad Name"}
              }
          },
          { $addFields: {uniqueAdsCount: {$size: "$uniqueAdNames"}}},
          {
            $group: 
              {
                _id: 
                  {
                    ProjectId: "$_id.ProjectId",
                    BuildId: "$_id.BuildId",
                    campaignName: "$_id.campaignName"
                  },
                  uniqueAdsCount: {$first: "$uniqueAdsCount"},
                  uniqueAdSets: {$addToSet: "$_id.adSet"}
              }
          },
          { $addFields: {uniqueAdsetCount: {$size: "$uniqueAdSets"}}},
          {
            $group: 
              {
                _id:{ProjectId: "$_id.ProjectId", BuildId: "$_id.BuildId"},
                uniqueAdsCount: {$first: "$uniqueAdsCount"},
                uniqueAdsetCount: {$first: "$uniqueAdsetCount"},
                uniqueCampaignNames: {$addToSet: "$_id.campaignName"}
              }
          },
          { $addFields: {uniqueCampaignCount: {$size: "$uniqueCampaignCount"}}},
          {
            $group: 
             {
               _id: "$projectId",
               Builds: {$push: "$_id.BuildId"},
               uniqueAdsCount: {$sum: "$uniqueAdsCount"},
               uniqueAdsetCount: {$sum: "$uniqueAdsetCount"},
               uniqueCampaignCount: {$sum: "$uniqueCampaignCount"}
              }
          },
          {
            $project:
             {
               _id: 0,
               ProjectId: "$_id.ProjectId",
               Builds: 1,
               BuildCountForProject: {$size: "$Builds"},
               uniqueAdsCount: 1,
               uniqueAdsetCount: 1,
               uniqueCampaignCount: 1,
             }
          }
       ])
    

    【讨论】:

    • 感谢 veeram,终于找到了我想要的东西。这是很好的逻辑,您如何在每个阶段对父元素进行分组并一次找到 1 个子元素的数量,然后继续使用 $first 将它们带到最后一个阶段。这简直太棒了。
    猜你喜欢
    • 2022-01-09
    • 1970-01-01
    • 2023-04-09
    • 2016-08-19
    • 1970-01-01
    • 2020-06-29
    • 2017-11-11
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多