J'ai 2 documents différents que je souhaite joindre en fonction d'un attribut spécifique. Sur le premier document, je veux utiliser $ group pour regrouper les documents en fonction d'un attribut, puis utiliser le résultat pour joindre un deuxième document.
Mon premier document spotmodel
a cette structure: p>
{ "_id" : ObjectId("5c16d339e6cbea23a0393b47"), "description" : "Area A", "streets" : [ { "_id" : ObjectId("5c16d3e6e6cbea23a0393b4b"), "name" : "Waterloo", "codes":[ { "code": "AD01" }, { "code": "AD02" } ] }, { "_id" : ObjectId("5c16d536e6cbea23a0393b51"), "name" : "Bristol" } ] }
Mon deuxième document areamodel
a la structure suivante:
db.spotmodel.aggregate([ { $group: { _id: "$streetId", codes: { $push: { code: "$code", } } } }, {$lookup: { from: "db.areamodel", localField: "streets._id", foreignField: "_id", as: "details" }}, {$match:{details:{$ne:[]}}} ])
Je souhaite regrouper mon spotmodel document basé sur le streetId
et utilisez cette requête groupée pour joindre le document areamodel
à tout moment streetId
correspond à rues ._id
Jusqu'à présent, j'ai la requête suivante:
{ "_id" : ObjectId("5c16d339e6cbea23a0393b47"), "description" : "Area A", "streets" : [ { "_id" : ObjectId("5c16d3e6e6cbea23a0393b4b"), "name" : "Waterloo" }, { "_id" : ObjectId("5c16d536e6cbea23a0393b51"), "name" : "Bristol" } ] } , { "_id" : ObjectId("5c16d339e6cbea23a0393b47"), "description" : "Area B", "streets" : [ { "_id" : ObjectId("5c16d3e6e6cbea23a0393b2a"), "name" : "Park Av." }, { "_id" : ObjectId("5c16d536e6cbea23a0393b2b"), "name" : "Nelson St." } ] }
mais ce code me donne un tableau vide [] code> mais le résultat que j'attends est quelque chose comme ceci:
{ "_id" : ObjectId("5c17724498ea721018ba9d59"), "code" : "AD01", "streetId" : ObjectId("5c16d3e6e6cbea23a0393b4b") }, { "_id" : ObjectId("5c17724498ea721018ba9d60"), "code" : "AD02", "streetId" : ObjectId("5c16d3e6e6cbea23a0393b4b") } // other documents with same or different streetID
Où est mon erreur?
3 Réponses :
Vous pouvez utiliser ci-dessous agrégation
db.areamodel.aggregate([ { "$unwind": "$streets" }, { "$lookup": { "from": "spotmodel", "localField": "streets._id", "foreignField": "streetId", "as": "codes" }}, { "$addFields": { "streets.codes": "$codes.code" }}, { "$group": { "_id": "$_id", "streets": { "$push": "$streets" }, "description": { "$first": "$description" } }} ])
La recherche est terriblement lente dans mongodb pour les grands ensembles de données. Essayez de dénormaliser vos documents.
// schema on nodejs via mongoose: var mongoose = require('mongoose') , Schema = mongoose.Schema , ObjectId = Schema.ObjectId; var flatSchema = new Schema({ _id: ObjectId, rentType: Number, price: Number, thumbnail: String, address: { country: String, city: String, street: String, district: Number // ... more fields } // ... some more fields }, { collection: 'flats'}); module.exports = mongoose.model('Flat', flatSchema); ----- / e.g. let's define request var rules = [{'address.city': '1'}, {price: {$gte: 200}}]; // and here are the grouping request: Flat.aggregate([ { $match: {$and: rules } }, { $project: { _id: 0, // let's remove bson id's from request's result price: 1, // we need this field district: '$address.district' // and let's turn the nested field into usual field (usual renaming) } }, { $group: { _id: '$district', // grouping key - group by field district minPrice: { $min: '$price'}, // we need some stats for each group (for each district) maxPrice: { $max: '$price'}, flatsCount: { $sum: 1 } } } ], {}, callback); First of all â itâs not possible to group by nested field, e.g. âaddress.districtâ, thats why we workarounded this by fieldâs renaming in $project.