I am trying to loop through something but first I need to do a mongo query to get the data for the loop my query is this:
AP.find({}, function(err, allAP) {
var ID = req.user.id;
if(err){
console.log(err);
} else {
res.locals.aps= allAP; // Set the data in locals
next();
}
});
I know I need to add something in the {} part on line 1. How do I take req.user.id and then only find documents with the author.id (see below)
author: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
email: String
}
Example document currently returned:
{ _id: 59e517230a892a26cb1b7635,
manufacturer: 'other',
model: 'Test Model',
bands: '2.4',
channel: 11,
notes: 'I am a test note for the first access point',
__v: 0,
author: { id: 59d7f98a77fcc221d6e3c93d, email: 'joe#example.com' } },
You can do
AP.find({"author.id":req.user.id}, function(err, allAP) {
if(err){
console.log(err);
} else {
res.locals.aps= allAP; // Set the data in locals
next();
}
});
Related
I am working with node(express) with mongoose and I have two collections,
Users
Comments
I added the sample Schema(added few fields only)
const UserSchema = mongoose.Schema({
name: String,
email: String,
});
const CommentsSchema = mongoose.Schema({
comments: String,
user_id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
text: String,
});
So I trying to fetch the users list and no of comments count based on user..
Expecting output like below:
data = [
{
name: 'abcd',
email: 'aa#test.com',
commentsCount: 5
},
{
name: 'xxx',
email: 'xx#test.com',
commentsCount: 3
}
]
I am not sure how to get the results, because we don;t have ref in user table..
userModel.find({}).exec((err, users) => {
if (err) {
res.send(err);
return;
}
users.forEach(function(user){
commentsModel.countDocuments({user_id: users._id}).exec((err, count) => {
if(!err){
user.commentsCount = count;
}
})
});
console.log('users', users)
});
Can you anyone please help to fix, I needs to list out the users and count of comments
i'm trying to do a pretty simple operation, pull an item from an array with Mongoose on a Mongo database like so:
User.update({ _id: fromUserId }, { $pull: { linkedUsers: [idToDelete] } });
fromUserId & idToDelete are both Objects Ids.
The schema for Users goes like this:
var UserSchema = new Schema({
groups: [],
linkedUsers: [],
name: { type: String, required: true, index: { unique: true } }
});
linkedUsers is an array that only receives Ids of other users.
I've tried this as well:
User.findOne({ _id: fromUserId }, function(err, user) {
user.linkedUsers.pull(idToDelete);
user.save();
});
But with no luck.
The second option seem to almost work when i console the lenghts of the array at different positions but after calling save and checking, the length is still at 36:
User.findOne({ _id: fromUserId }, function(err, user) {
console.log(user.linkedUsers.length); // returns 36
user.linkedUsers.pull(idToDelete);
console.log(user.linkedUsers.length); // returns 35
user.save();
});
So it looks like i'm close but still, no luck. Both Ids are sent via the frontend side of the app.
I'm running those versions:
"mongodb": "^2.2.29",
"mongoose": "^5.0.7",
Thanks in advance.
You need to explicitly define the types in your schema definition i.e.
groups: [{ type: Schema.Types.ObjectId, ref: 'Group' }],
linkedUsers: [{ type: Schema.Types.ObjectId, ref: 'User' }]
and then use either
User.findOneAndUpdate(
{ _id: fromUserId },
{ $pullAll: { linkedUsers: [idToDelete] } },
{ new: true },
function(err, data) {}
);
or
User.findByIdAndUpdate(fromUserId,
{ $pullAll: { linkedUsers: [idToDelete] } },
{ new: true },
function(err, data) {}
);
I had a similar issue. I wanted to delete an object from an array, using the default _id from mongo, but my query was wrong:
const update = { $pull: { cities: cityId }};
It should be:
const update = { $pull: { cities: {_id: cityId} }};
When I save a new "experience" document with the model Experience, the experience _id is not saved into the document of the user. So my "experiences" array in the user document remains empty. Why?
const mongoose = require('mongoose');
const ExperienceSchema = mongoose.Schema({
name: String,
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
reviews: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Review' }],
categories: [{ type: String }],
});
module.exports = mongoose.model('Experience', ExperienceSchema);
==============================================
const mongoose = require('mongoose');
const UserSchema = mongoose.Schema({
name: String,
experiences: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Experience' }],
});
module.exports = mongoose.model('User', UserSchema);
=============================================
// Update experience to database
router.post('/:id', (req, res, next) => {
const idexp = req.params.id;
const newExperience = {
name: req.body.name,
user: req.user._id,
};
Experience.findOneAndUpdate({ _id: idexp }, newExperience, (err, result) => {
if (err) {
return res.render(`/${idexp}/edit`, { errors: newExperience.errors });
}
return res.redirect(`/experiences/${idexp}`);
});
});
The experiences is the sub-document of user schema. So, when you save experiences, the user will not be saved. However, when you save user, the experience should be saved.
Refer this subdocs documentation
Here is the solution... I needed to use $push to update the user document with the experience id before rendering the site.
Experience.findOneAndUpdate({ _id: idexp }, newExperience, (err, result) => {
if (err) {
return res.render('experiences/edit', { errors: newExperience.errors });
}
User.findByIdAndUpdate({ _id: req.session.passport.user._id }, { $push: { experiences: idexp } }, (err) => {
if (err) {
next(err);
} else {
return res.redirect(`/experiences/${idexp}`);
}
});
});
In the docs of waterline it is stated that this is the way to perform a IN query on a model:
Model.find({
name : ['Walter', 'Skyler']
});
And this the way to perform an OR query on a model:
Model.find({
or : [
{ name: 'walter' },
{ occupation: 'teacher' }
]
})
My problem now is that i need a combination of those two, and to make it even more complicated, one of the attributes i have to use is a collection.
So what i tried is this, but it doesn't seem to work:
Product.find({
or : [
{ createdBy: userIds },
{ likes: userIds }
]
})
Note: userIds is an array of id's from a user model.
The (simplified) product model looks likes this:
module.exports = {
attributes: {
name: 'string',
description: 'string',
createdBy: {
model: 'User'
},
brand: {
model: 'Brand',
},
likes: {
collection: 'User',
}
}
}
The query works when I only include createdBy, so it seems to be a problem with the collection attribute.
Is this somehow possible?
Thank you for your input.
UPDATE:
I think this is only possible with native() queries.
The way I understand it something like this should work.
Product.native(function(err, products){
if(err) return res.serverError(err);
products.find({"likes": { $elemMatch: { _id: { $in: userIds}}}}).toArray(function(err, results){
if (err){
console.log('ERROR', err);
}
else {
console.log("found products: " + results.length);
console.log(results);
return res.ok(results);
}
});
});
Unfortunately, it doesn't. The returned results is always an empty array.
In Article model, I want to save a list of categories:
var CategorySchema = new Schema({
name: String,
active: Boolean
});
var ArticleSchema = new Schema({
title: String,
description: String,
categories: [{ type : Schema.Types.ObjectId, ref: 'Category' }]
})
From the endpoint, I want to update article with categories. The update method looks like:
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
Article.findById(req.params.id, function (err, article) {
if (err) { return handleError(res, err); }
if(!article) { return res.send(404); }
var updated = _.merge(article, req.body);
updated.save(function (err, doc) {
console.log(doc);
if (err) { return handleError(res, err); }
return res.json(200, article);
});
});
};
Notice the console.log statement. In request.body, if I'm sending list of category ids, the console prints out an article with categories. However, when I look into the database, the category array is empty. Any pointer to how to solve this?