Reputation: 599
I haven't done much work with mongo so coming from mysql it is a bit of a challenge. What I want to do is get the data for the users in my friends array ie: their name, email etc. This is what I have below. When I hit a certain route I send my ID to the api endpoint. I then need to get the friend ID's from the array and get their relevant information.
Record in the database
{
"_id": {
"$oid": "5f1b22a427e4624711bdef0e"
},
"friends": [{
"$oid": "5f206e15e9b66391246788d6"
}, {
"$oid": "5f2456777656525890dd9c21"
}],
"name": "Joe Smith",
"email": "[email protected]",
"mobile": "1233455467889",
}
Controller
exports.getAddedContacts = async (req, res) => {
const userId = req.params.uid;
let friends;
try {
friends = await User.find({ _id: userId });
} catch (err) {
res
.status(500)
.json({ error: "Something went wrong, could not get contacts" });
}
if (!friends || friends.length === 0) {
res.status(404).json({ error: "No contacts found..." });
}
res.status(200).json({ friends: friends });
};
Upvotes: 0
Views: 775
Reputation: 584
You could use an aggregation where you would use $match as the first stage in you pipeline just so you isolate only one user and then use populate to get your friends documents.
here is an example:
db.classes.insert( [
{ _id: 1, title: "Reading is ...", enrollmentlist: [ "giraffe2", "pandabear", "artie" ], days: ["M", "W", "F"] },
{ _id: 2, title: "But Writing ...", enrollmentlist: [ "giraffe1", "artie" ], days: ["T", "F"] }
])
db.members.insert( [
{ _id: 1, name: "artie", joined: new Date("2016-05-01"), status: "A" },
{ _id: 2, name: "giraffe", joined: new Date("2017-05-01"), status: "D" },
{ _id: 3, name: "giraffe1", joined: new Date("2017-10-01"), status: "A" },
{ _id: 4, name: "panda", joined: new Date("2018-10-11"), status: "A" },
{ _id: 5, name: "pandabear", joined: new Date("2018-12-01"), status: "A" },
{ _id: 6, name: "giraffe2", joined: new Date("2018-12-01"), status: "D" }
])
db.classes.aggregate([
{
$match: {
_id: 1
}
}
{
$lookup:
{
from: "members",
localField: "enrollmentlist",
foreignField: "name",
as: "enrollee_info"
}
}
])
You can find out more about this in official documentation
Just watch out for the result, aggregation always returns a list you so you have to do something like const [user] = await result.toArray()
Since you use mongoose you could also try using populate (check out docs) on your model like so:
const author = new Person({
_id: new mongoose.Types.ObjectId(),
name: 'Ian Fleming',
age: 50
});
author.save(function (err) {
if (err) return handleError(err);
const story1 = new Story({
title: 'Casino Royale',
author: author._id // assign the _id from the person
});
story1.save(function (err) {
if (err) return handleError(err);
// that's it!
});
});
Story.
findOne({ title: 'Casino Royale' }).
populate('author').
exec(function (err, story) {
if (err) return handleError(err);
console.log('The author is %s', story.author.name);
// prints "The author is Ian Fleming"
});
NOTE: I noticed in your question that you are storing what should be an array of ObjectID
-s as an array of objects containing a single field string representing an ObjectID
, this has to be changed if you want populate or lookup to work.
Upvotes: 1