Imagina dos colecciones de mongo.
FirstCollection tiene este formato:
{ "JoinField": "this is my data" }SecondCollection tiene este formato (los datos reales son más complejos y necesitan aplanarse):
{ "FirstField" : "food", "SecondField": "bar", "Properties" : { "JoinField": "this is my data" } }SecondCollection contiene duplicados y estoy tratando de unir las dos tablas y aplanar los datos en una sola proyección.
Esta consulta hará en términos generales lo que quiero:
db.getCollection('FirstCollection').aggregate([ { "$lookup": { from: 'SecondCollection', localField: 'JoinField', foreignField: 'Properties.JoinField', as: 'secondCollection' } }, { "$unwind": "$secondCollection" }, { "$project": { "JoinField" : 1, firstField : "$secondCollection.FirstField", secondField : "$secondCollection.SecondField", } } ])El único problema es que esto contiene duplicados en sí mismo porque repite los datos para cada duplicado en SecondCollection que coincide con una línea en FirstCollection.
¿Cómo puedo obtener solo el primer registro (o cualquier copia individual del registro) de SecondCollection?
EDITAR: Disculpas por la falta de claridad. Lo que obtendré actualmente de esa consulta, suponiendo un duplicado en SecondCollection, es esto:
{ "JoinField": "this is my data". "FirstField" : "food", "SecondField": "bar" } { "JoinField": "this is my data". "FirstField" : "food", "SecondField": "bar" }Lo que quiero es esto:
{ "JoinField": "this is my data". "FirstField" : "food", "SecondField": "bar" }Intente buscar con canalización de agregación de MongoDB v3.6,
let pasar el campo local a la segunda tubería de recolección,pipeline para hacer coincidir el campo y establecer un límite para devolver un solo documento { "$lookup": { from: "SecondCollection", let: { "jfield": "$JoinField" }, pipeline: [ { $match: { $expr: { $eq: ["$Properties.JoinField", "$$jfield"] } } }, { $limit: 1 } ], as: "secondCollection" } }, Segunda opción de MongoDB v3.2, coloque una etapa $set después $lookup y antes $unwind ,
$arrayElemAt elemento devuelto desde una posición específica { $set: { secondCollection: { $arrayElemAt: ["$secondCollection", 0] } } }Si entiendo bien la pregunta, podrías probar esto
db.b.aggregate([ //Used second collection as the source { "$group": { //Removing duplicates in the join field "_id": "$properties.joinField", FirstField: { "$addToSet": "$FirstField" }, SecondField: { "$addToSet": "$SecondField" }, "JoinField": { $first: "$Properties.JoinField" } } }, { "$lookup": { from: "a", localField: "JoinField", foreignField: "JoinField", as: "FirstCollection" } }, { "$unwind": "$FirstCollection" }, { "$project": { "JoinField": 1, firstField: "$FirstField", secondField: "$SecondField", } } ])