如何聚合两个 collections 并将字段与数组匹配
How to ggregate two collections and match field with array
我需要将两个 collection candidatos
和 ofertas
的结果分组,然后将这些组“合并”到 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 }
])
注意:如果您只需要进行聚合,这很好。但是我个人觉得这种做法并不好。我的建议是,您可以同时调用不同服务中的组聚合并以编程方式进行。因为$lookup
是昂贵的,当你得到海量数据时,这个性能会降低
$cond
中的 $eq
正在将数组与 ObjectId 进行比较,因此永远不会匹配。
$lookup
阶段结果将在 ofertas
字段中作为文档数组,因此 '$ofertas._id'
将是所有 _id 值的数组。
您可能需要在 $lookup
之后使用 $unwind
、$reduce
。
我需要将两个 collection candidatos
和 ofertas
的结果分组,然后将这些组“合并”到 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 }
])
注意:如果您只需要进行聚合,这很好。但是我个人觉得这种做法并不好。我的建议是,您可以同时调用不同服务中的组聚合并以编程方式进行。因为$lookup
是昂贵的,当你得到海量数据时,这个性能会降低
$cond
中的 $eq
正在将数组与 ObjectId 进行比较,因此永远不会匹配。
$lookup
阶段结果将在 ofertas
字段中作为文档数组,因此 '$ofertas._id'
将是所有 _id 值的数组。
您可能需要在 $lookup
之后使用 $unwind
、$reduce
。