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

时间:2021-06-01 09:58:04

标签: mongodb aggregate

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

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

https://mongoplayground.net/p/m0PUfdjEye4

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

我可以独立获得两个组的预期结果:

候选人收集:

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

这是结果...

enter image description here

ofertas 集合:

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

这是结果...

enter image description here

我需要做的是聚合这些组,根据他们的 _id 巧合合并他们的结果。我想我会以正确的方式处理下一个聚合,但字段 countOfertas 总是返回 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

enter image description here

欢迎任何形式的帮助

2 个答案:

答案 0 :(得分:1)

非常感谢您的尝试。但是在 $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很贵,当你得到海量数据时,这个性能会降低

答案 1 :(得分:1)

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

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

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