mongodb - 如何在 mongoDB 中按嵌套文档进行分组

标签 mongodb aggregation-framework aggregate

我最近开始学习mongoDB,并做了一些例子来提高自己。我有一个问题,我无法想象如何在 mongoDB 中做到这一点,或者这真的有可能实现。所以我需要你的帮助。

首先,我有一个这样的收藏;

/* 1 */
{
    "_id" : ObjectId("62372c37ea4cbb005e97ec1c"),
    "CreatedTime" : ISODate("2022-03-20T13:29:27.456Z"),
    "UpdatedTime" : Date(-62135596800000),
    "Name" : "Name1",
    "Surname" : "Surname1",
    "Company" : "Company1",
    "ContactInformation" : null
}

/* 2 */
{
    "_id" : ObjectId("62372c37ea4cbb005e97ec1d"),
    "CreatedTime" : ISODate("2022-03-20T13:29:27.456Z"),
    "UpdatedTime" : Date(-62135596800000),
    "Name" : "Name2",
    "Surname" : "Surname2",
    "Company" : "Company2",
    "ContactInformation" : [ 
        {
            "InfoType" : 1,
            "Info" : "+905554443322"
        }, 
        {
            "InfoType" : 3,
            "Info" : "İstanbul"
        }
    ]
}

/* 3 */
{
    "_id" : ObjectId("62372c37ea4cbb005e97ec1e"),
    "CreatedTime" : ISODate("2022-03-20T13:29:27.456Z"),
    "UpdatedTime" : Date(-62135596800000),
    "Name" : "Name3",
    "Surname" : "Surname3",
    "Company" : "Company3",
    "ContactInformation" : [ 
        {
            "InfoType" : 1,
            "Info" : "+905554443301"
        }, 
        {
            "InfoType" : 1,
            "Info" : "+905554443302"
        }, 
        {
            "InfoType" : 3,
            "Info" : "Kastamonu"
        }
    ]
}

/* 4 */
{
    "_id" : ObjectId("62372c37ea4cbb005e97ec1f"),
    "CreatedTime" : ISODate("2022-03-20T13:29:27.456Z"),
    "UpdatedTime" : Date(-62135596800000),
    "Name" : "Name4",
    "Surname" : "Surname4",
    "Company" : "Company4",
    "ContactInformation" : [ 
        {
            "InfoType" : 3,
            "Info" : "Kastamonu"
        }
    ]
}

信息类型:1 - 电话号码,3 - 位置(城市、国家等) Info 是 InfoTypes 的值

然后我想得到一个包含三个值的报告;

  • 位置信息(如果文档有 InfoType 为 3 的嵌套文档)
  • 所属位置的记录数
  • 属于该位置的电话号码

预期输出:

{
 location: "İstanbul",
 recordCount: 1,
 phoneNumCount: 1
},
{
 location: "Kastamonu",
 recordCount: 2,
 phoneNumCount: 2
}

前两个条件可以,我可以得到它们,但第三个条件我不能。

感谢大家的帮助

最佳答案

尝试以下管道:

  1. 查找用户所在的国家/地区并使用 $addFields 将其添加为字段。如果 null,还要添加 ContactInformation 作为空数组。
  2. 使用$group按用户所在国家/地区对文档进行分组。然后使用$count计算记录数和 $sum该国家/地区的电话号码。
[
  {
    $addFields: {
      country: {
        $arrayElemAt: [
          {
            $filter: {
              input: "$ContactInformation",
              as: "info",
              cond: {
                $eq: [
                  "$$info.InfoType",
                  3
                ]
              }
            }
          },
          0
        ]
      },
      ContactInformation: {
        $ifNull: [
          "$ContactInformation",
          []
        ]
      }
    }
  },
  {
    $group: {
      _id: "$country.Info",
      recordCount: {
        $count: {}
      },
      phoneNumCount: {
        $sum: {
          $size: {
            $filter: {
              input: "$ContactInformation",
              as: "info",
              cond: {
                $eq: [
                  "$$info.InfoType",
                  1
                ]
              }
            }
          }
        }
      }
    }
  }
])

Mongo Playground

关于mongodb - 如何在 mongoDB 中按嵌套文档进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71547894/

相关文章:

c# - 使用聚合连接 linq 将结果放入 POCO

c# - LINQ.Aggregate 返回不正确的结果

mongodb - mongod 主进程被 KILL 信号杀死

node.js - 如果第三个键为 true,则比较 mongodb 文档的两个键

mongodb - webflux 返回一个空对象列表

c# - MongoDB.net 驱动程序 - 项目到不同的类

javascript - 如何在 Node ,expressjs中的 Elasticsearch 中从 Mongoose 创建索引

mongodb - 组合数组中的唯一项

mongodb - 通过 mod(ObjectId) 选择文档的一部分

python - 如何在 Pandas 的 groupby 之后获取列的计数百分比