如何聚合两个 collections 并将字段与数组匹配

How to ggregate two collections and match field with array

我需要将两个 collection candidatosofertas 的结果分组,然后将这些组“合并”到 return 具有匹配值的数组。

我使用聚合数据和类似数据创建了这个示例,以使其更易于测试:

https://mongoplayground.net/p/m0PUfdjEye4

这是对我面临的问题的解释。

我可以独立地让两组都获得所需的结果:

候选人collection:

db.getCollection('ofertas').aggregate([
{"$group" : {_id:"$ubicacion_puesto.provincia", countProvinciaOferta:{$sum:1}}} 
 ]);

这是结果...

奥弗塔斯 collection:

db.getCollection('candidatos').aggregate([
{"$group" : {_id:"$que_busco.ubicacion_puesto_trabajo.provincia", countProvinciaCandidato:{$sum:1}}} 
 ]);

这是结果...

我需要做的是聚合这些组以根据它们的 _id 巧合合并它们的结果。我认为我将以正确的方式处理下一个聚合,但字段 countOfertas 总是 returns 0.0。我认为我的 project $cond 有问题,但我不知道是什么。这是合计:

db.getCollection('candidatos').aggregate([
    {"$group" : {_id:"$que_busco.ubicacion_puesto_trabajo.provincia", countProvinciaCandidato:{$sum:1}}},
    
            {
            $lookup: {
                from: 'ofertas',
                let: {},
                pipeline: [
                    {"$group" : {_id:"$ubicacion_puesto.provincia", countProvinciaOferta:{$sum:1}}} 
                ],
                as: 'ofertas'
            }
        },
     
       {
    $project: {
        _id: 1,
        countProvinciaCandidato: 1,
      countOfertas: {
          $cond: {
            if: {
              $eq: ['$ofertas._id', "$_id"]
            },
            then: '$ofertas.countProvinciaOferta',
            else: 0,
          }
      }
    }
  },   
        { $sort: { "countProvinciaCandidato": -1}},
        { $limit: 20 }
 ]); 

这是结果,但是如您所见,字段 countOfertas 始终为 0

欢迎任何形式的帮助

非常感谢您的尝试。但是在 $project 你需要使用 $reduce 这有助于遍历数组并满足条件

这是代码

db.candidatos.aggregate([
  {
    "$group": {
      _id: "$que_busco.ubicacion_puesto_trabajo.provincia",
      countProvinciaCandidato: { $sum: 1 }
    }
  },
  {
    $lookup: {
      from: "ofertas",
      let: {},
      pipeline: [
        {
          "$group": {
            _id: "$ubicacion_puesto.provincia",
            countProvinciaOferta: { $sum: 1 }
          }
        }
      ],
      as: "ofertas"
    }
  },
  {
    $project: {
      _id: 1,
      countProvinciaCandidato: 1,
      countOfertas: {
        "$reduce": {
          "input": "$ofertas",
          initialValue: 0,
          "in": {
            $cond: [
              { $eq: [ "$$this._id", "$_id" ] },
              { $add: [ "$$value", 1 ] },
              "$$value"
            ]
          }
        }
      }
    }
  },
  { $sort: { "countProvinciaCandidato": -1 } },
  { $limit: 20 }
])

工作Mongo playground

注意:如果您只需要进行聚合,这很好。但是我个人觉得这种做法并不好。我的建议是,您可以同时调用不同服务中的组聚合并以编程方式进行。因为$lookup是昂贵的,当你得到海量数据时,这个性能会降低

$cond 中的 $eq 正在将数组与 ObjectId 进行比较,因此永远不会匹配。

$lookup 阶段结果将在 ofertas 字段中作为文档数组,因此 '$ofertas._id' 将是所有 _id 值的数组。

您可能需要在 $lookup 之后使用 $unwind$reduce