Reputation: 16699
One member is part of one or many groups. One group can have one or many members.
Given one member, and the groups he is in, how can I obtain the other members in each of those groups?
var MemberSchema = new Schema(
{
name: {
first: { type: String },
last: { type: String },
},
groups: [ { type: String } ],
otherMembersInGroups: [ {
id: { type: Schema.ObjectId, ref: 'Member' } ,
name: {
first: { type: String },
last: { type: String },
}
} ],
});
var query = MemberModel.findOne( { _id: objId } );
query.exec( function( err, member )
{
// TODO: get all the members in all the groups that this member is in
var otherMembersInGroups = magicHere();
member.otherMembersInGroups = otherMembersInGroup;
return res.send( 200, member );
}
My starting point is
var query = MemberModel.find( { groups: "groupNamesHere" } )
but I don't really understand how to combine it with the above.
Also: How do I add this field to the mongoose model correctly? I tried, but there is a lot of duplication (see above). But it seems that without adding it to the model, it doesn't actually get added to the member object?
Upvotes: 0
Views: 82
Reputation: 151230
For mine I would not be so formal with the "Schema" definition and handle it a little differently. Considering a schema defined like:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var memberSchema = new Schema({
name: {
first: { type: String },
last: { type: String }
},
groups: [ { type: String } ]
});
var Member = mongoose.model( 'Member', memberSchema );
With data like this:
{
"_id" : ObjectId("53708c9865a6272f6e26c9bf"),
"groups" : [ "tennis" ],
"name" : { "first" : "Ted", "last" : "Logan" },
"__v" : 0
}
{
"_id" : ObjectId("53708cb33905d7846ee2a218"),
"groups" : [ "tennis", "hockey" ],
"name" : { "first" : "Bill", "last" : "Preston" },
"__v" : 0
}
{
"_id" : ObjectId("53708cd200155f916e9248f6"),
"groups" : [ "perl", "hockey" ],
"name" : { "first" : "Fozzie", "last" : "Bear" },
"__v" : 0
}
{
"_id" : ObjectId("53708ce7c95556e66ee4967f"),
"groups" : [ "perl", "hockey" ],
"name" : { "first" : "Serena", "last" : "Williams" },
"__v" : 0
}
The rest of the operation becomes like this:
Member.findOne({ _id: "53708cb33905d7846ee2a218" },function(err,member) {
Member.find({
"groups": { "$in": member.groups },
"_id": { "$nin": [ member._id ] }
},function(err, others) {
var data = {
name: member.name,
groups: member.groups,
otherMembers: []
};
others.forEach(function(other) {
var doc = {};
doc.name = other.name;
doc._id = other._id;
data.otherMembers.push( doc );
});
console.log( data );
});
});
Of course replacing that console.log()
part with your actual API function. But generally a raw object has less rules to manipulate than a "schema" and is therefore just a bit easier to control your results.
Also make sure you have an index specified in that order where "groups" is the first element in order to optimize this.
Upvotes: 1