const fs = require('fs'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
mongoose.set('debug',true);
const uri = 'mongodb://localhost/nested',
options = { useMongoClient: true };
const responseSchema = new Schema({
response_text: String,
order: String,
created_date: Date,
question: { type: Schema.Types.ObjectId, ref: 'Question' }
});
const questionSchema = new Schema({
question_text: String,
order: String,
created_date: Date,
group: { type: Schema.Types.ObjectId, ref: 'Group' }
},{
toJSON: {
virtuals: true,
transform: function(doc,obj) {
delete obj.id;
return obj;
}
}
});
questionSchema.virtual('responses',{
ref: 'Response',
localField: '_id',
foreignField: 'question'
});
const groupSchema = new Schema({
name: String,
order: String,
created_date: Date,
survey: { type: Schema.Types.ObjectId, ref: 'Survey' },
questions: [{ type: Schema.Types.ObjectId, ref: 'Question' }]
});
const surveySchema = new Schema({
company: { type: Schema.Types.ObjectId, ref: 'Company' },
created_date: Date,
enabled: Boolean,
name: String
},{
toJSON: {
virtuals: true,
transform: function(doc,obj) {
delete obj.id;
return obj;
}
}
});
surveySchema.virtual('groups',{
ref: 'Group',
localField: '_id',
foreignField: 'survey'
});
const companySchema = new Schema({
});
const Company = mongoose.model('Company', companySchema);
const Survey = mongoose.model('Survey', surveySchema);
const Group = mongoose.model('Group', groupSchema);
const Question = mongoose.model('Question', questionSchema);
const Response = mongoose.model('Response', responseSchema);
function log(data) {
console.log(JSON.stringify(data,undefined,2))
}
(async function() {
try {
const conn = await mongoose.connect(uri,options);
await Promise.all(
Object.keys(conn.models).map( m => conn.models[m].remove() )
);
// Initialize data
let content = JSON.parse(fs.readFileSync('./jsonSurveys.json'));
//log(content);
for ( let item of content ) {
let survey = await Survey.create(item);
let company = await Company.create({ _id: survey.company });
for ( let group of item.groups ) {
await Group.create(group);
for ( let question of group.questions ) {
await Question.create(question);
for ( let response of question.responses ) {
await Response.create(response);
}
}
}
}
// Run aggregation
let results = await Survey.aggregate([
{ "$lookup": {
"from": Group.collection.name,
"localField": "_id",
"foreignField": "survey",
"as": "groups"
}},
{ "$unwind": "$groups" },
{ "$lookup": {
"from": Question.collection.name,
"localField": "groups.questions",
"foreignField": "_id",
"as": "groups.questions"
}},
{ "$unwind": "$groups.questions" },
{ "$lookup": {
"from": Response.collection.name,
"localField": "groups.questions._id",
"foreignField": "question",
"as": "groups.questions.responses"
}},
{ "$group": {
"_id": {
"_id": "$_id",
"company": "$company",
"created_date": "$created_date",
"enabled": "$enabled",
"name": "$name",
"groups": {
"_id": "$groups._id",
"name": "$groups.name",
"order": "$groups.order",
"created_date": "$groups.created_date",
"survey": "$groups.survey"
}
},
"questions": { "$push": "$groups.questions" }
}},
{ "$sort": { "_id": 1 } },
{ "$group": {
"_id": "$_id._id",
"company": { "$first": "$_id.company" },
"created_date": { "$first": "$_id.created_date" },
"enabled": { "$first": "$_id.enabled" },
"name": { "$first": "$_id.name" },
"groups": {
"$push": {
"_id": "$_id.groups._id",
"name": "$_id.groups.name",
"order": "$_id.groups.order",
"created_date": "$_id.groups.created_date",
"survey": "$_id.groups.survey",
"questions": "$questions"
}
}
}},
{ "$sort": { "_id": 1 } }
]);
log(results);
let alternate = await Survey.find().populate({
path: 'groups',
populate: {
path: 'questions',
populate: {
path: 'responses'
}
}
});
log(alternate);
} catch(e) {
console.error(e);
} finally {
mongoose.disconnect();
}
})();