Reputation: 131
I have 6 Different Collections in my mongodb, the 5 collections are to connected to one connection, But I didn't used ref, instead I made is that I get the Id of 5 collections and then saved it to the 6th collection namely "List" so that I still have common field that I can use as a reference
Here is my Collections structure
list Collection
var ListDoc = new mongoose.Schema({
type_id : {type: Schema.Types.ObjectId, required: true},
detail_id : {type: Schema.Types.ObjectId, required: true},
address_id : {type: Schema.Types.ObjectId, required: true},
inquiries_id : {type: Schema.Types.ObjectId, required: true},
account_id : {type: Schema.Types.ObjectId, required: true}
});
module.exports = mongoose.model('List', ListDoc);
Account Collection
var accountDoc = new mongoose.Schema({
email : {type: String, unique: true, required: true},
password : {type: String, required: true}
});
module.exports = mongoose.model('Accounts', accountDoc );
Type Collection
var TypeDoc = new mongoose.Schema({
type : {type: String, required: true},
class : {type: String, required: true},
});
module.exports = mongoose.model('Type', TypeDoc);
Detail Collection
var DetailDoc = new mongoose.Schema({
bedr : {type: Number, required: true},
diningr : {type: Number, required: true},
livingr : {type: Number, required: true},
kitchenr : {type: Number, required: true}
bathr : {type: Number, required: true}
});
module.exports = mongoose.model('Detail', DetailDoc);
Address Collection
var AddressDoc = new mongoose.Schema({
city : {type: String, required: true},
brgy : {type: String, required: true},
street : {type: String, required: true},
bldgno : {type: String, required: true},
floorno : {type: String, required: true},
roomno : {type: String, required: true}
});
module.exports = mongoose.model('Address', AddressDoc);
Inquiries Collection
var InquiriesDoc = new mongoose.Schema({
inquiries : {type: Number, required: true},
views : {type: Number, required: true},
});
module.exports = mongoose.model('Inquiries', InquiriesDoc);
Note: each collection has different .js file
The list Collection will have the Ids of 4 another Collection.
This is what Im trying to achieve
[ {
"_id": "5907747e424c860f7495ad46",
"account_id": "5908f3381cd9810ea8e2b517",
"type": {
"type" : "apartment",
"class" : "middle"
},
"detail": {
"bedr": 4,
"diningr": 2,
"livingr": 1,
"kitchenr": 1,
"bathr": 4
},
"address": {
"city" : "lucena",
"brgy" : "8",
"street" : "rose",
"bldgno" : "24",
"floorno": "2",
"roomno": "205"
},
"inquiries": {
"views" : 0,
"inquires" : 0
}
},
{
"_id": "5907747e424c860f7495ad47",
"account_id": "5908f3381cd9810ea8e2b517",
"type_id": {
"type" : "apartment",
"class" : "middle"
},
"detail": {
"bedr": 4,
"diningr": 2,
"livingr": 1,
"kitchenr": 1,
"bathr": 4
},
"address": {
"city" : "lucena",
"brgy" : "8",
"street" : "rose",
"bldgno" : "24",
"floorno": "3",
"roomno": "307"
},
"inquiries": {
"views" : 0,
"inquires" : 0
}
}, ]
First I get all the data inside the list collection which is the Ids of 4 Collection and then I tried to loop it so that I can get the another data from other collections
for(var loop =0 ; loop < list.length; loop++){
var pt_id = list[loop].type_id;
var pa_id = list[loop].address_id;
var pd_id = list[loop].detail_id;
var pi_id = list[loop].inquiries_id;
}
I'd use async inside for loop then concate it into "testresult" var using +=
here is my code
var PL = require('../models/list');
var PT = require('../models/type');
var PA = require('../models/address');
var PD = require('../models/detail');
var PI = require('../models/inquiry');
var cryption = require('../services/encrypt_decrypt');
var crypt = new cryption();
var async = require('async');
module.exports.read = function (request, response) {
var decryptedId = crypt.decrypt(request.decode.id);
var propertylistquery = PL.find({}).where('account_id').equals(decryptedId).select({"_id":0,"__v":0});
propertylistquery.exec(function (error, list) {
if (error) {
return response.status(500).send({success: false, error: error, message: 'Something went wrong.'});
}
if (!list) {
return response.status(200).send({success: false, message: 'User not found in the database.'});
}
var testresult;
for(var loop =0 ; loop < list.length; loop++){
var pt_id = list[loop].type_id;
var pa_id = list[loop].address_id;
var pd_id = list[loop].detail_id;
var pi_id = list[loop].inquiries_id;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Getting the property type
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var ptquery = PT.find({}).where('_id').equals(pt_id).select({"__v":0});
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Getting the property address
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var paquery = PA.find({}).where('_id').equals(pa_id).select({"__v":0});
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Getting the property detail
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var pdquery = PD.find({}).where('_id').equals(pd_id).select({"__v":0});
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Getting the propertyinquiry
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var piquery = PI.find({}).where('_id').equals(pi_id).select({"__v":0});
var resources = {
Type : ptquery.exec.bind(ptquery),
Address : paquery.exec.bind(paquery),
Detail : pdquery.exec.bind(pdquery),
Inquiry : piquery.exec.bind(piquery)
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Asynchrozing the queries
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
async.parallel(resources, function (error, results){
if (error) {
response.status(500).send(error);
return;
}
testresult += results;
//console.log(results);
});
}
console.log(testresult);
response.json({success: true, data: list, message: 'Successfully fetched all property.'});
});
};
when I log the "result" var inside for loop, it has a data but when I try to log the "testresult" var, it is undefined
What will I do get my desire output?
Upvotes: 1
Views: 766
Reputation: 103475
Just use the $lookup
operator to do the joins from the other collections where you can specify the collection in the same database to perform the join with and the results stored in an array field added to the input documents.
The following example demonstrates the operation with $lookup
. To get the desired output you would then need to apply the $arrayElemAt
operator on the resulting arrays, this will return the subdocument in the array specified by an index, 0 in this case as it's the only element
in the array (result of a one-to-one relationship will give a single element array with $lookup
):
var PL = require('../models/list');
var cryption = require('../services/encrypt_decrypt');
var crypt = new cryption();
module.exports.read = function (request, response) {
var decryptedId = crypt.decrypt(request.decode.id);
PL.aggregate([
{ "$match": { "account_id": mongoose.Types.ObjectId(decryptedId) } },
{
"$lookup": {
"from": "pt", /* make sure the underlying collection name is correct */
"localField": "type_id",
"foreignField": "_id",
"as": "types"
}
},
{
"$lookup": {
"from": "pa", /* make sure the underlying collection name is correct */
"localField": "address_id",
"foreignField": "_id",
"as": "addresses"
}
},
{
"$lookup": {
"from": "pd", /* make sure the underlying collection name is correct */
"localField": "detail_id",
"foreignField": "_id",
"as": "details"
}
},
{
"$lookup": {
"from": "pi", /* make sure the underlying collection name is correct */
"localField": "inquiries_id",
"foreignField": "_id",
"as": "inquiries"
}
},
{
"$project": {
"account_id": 1,
"type": { "$arrayElemAt": ["$types", 0] },
"detail": { "$arrayElemAt": ["$addresses", 0] },
"address": { "$arrayElemAt": ["$details", 0] },
"inquiries": { "$arrayElemAt": ["$inquiries", 0] },
}
}
]).exec(function (error, results){
if (error) {
response.status(500).send(error);
}
console.log(results);
response.json({
success: true,
data: results,
message: 'Successfully fetched all property.'
});
});
};
Upvotes: 1