This question already has answers here:
Join two collections using mongoose and get data from both
(1 answer)
Mongoose populate does not populate array
(3 answers)
How to populate array of objects in mongoose
(2 answers)
Closed 11 months ago.
I am trying to pull data (particularly, the memberships array) from a certain user.
_id:623db49b9da63a7758307d68
email:"test#test.com"
username:"test"
salt:"eb83e08efef62630c46b1809c7671db2109ceccff9d66862c93df1e3825c1354"
hash:"e419edb1bc481d5c87dd223a7f1dc20bece679fad1a3c1afe05dfabba341c0a9913a60..."
__v:0
memberships:Array
0:623dc03f72436863b72c396e
1:623dc869b61c3799494b2657
However, when I request the document, it does not retrieve the memberships portion.
{
_id: new ObjectId("623db49b9da63a7758307d68"),
email: 'test#test.com',
username: 'test',
__v: 0
}
The code below is responsible for pulling the information from the DB and then also logs what was pulled.
module.exports.showContent = async(req, res, next) => {
try {
const user = await User.findById(req.user.id);
console.log(user)
res.render('index', { user })
} catch (e) {
console.log(e)
res.render('index')
}
}
Funny enough, if there is only one ref in the array, it will show up in the console.log!
{
_id: new ObjectId("623db49b9da63a7758307d68"),
email: 'test#test.com',
username: 'test',
__v: 0,
memberships: new ObjectId("623dc869b61c3799494b2657")
}
Schema model in question:
const UserSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
},
username: {
type: String,
required: true,
unique: true,
},
roles: String,
memberships: {
type: Schema.Types.ObjectId,
ref: 'Community',
},
posts: {
type: Schema.Types.ObjectId,
ref: 'Posts',
},
comments: {
type: Schema.Types.ObjectId,
ref: 'Comments',
}
})
UserSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', UserSchema);
My other collections do not seem to have the same issue when it comes to refs inside an array.
I have tried using .populate() to populate the data. Tried using path: and populate: within the method. Tried googling the issue, but to no luck.
Related
This question already has answers here:
How to Update Multiple Array Elements in mongodb
(16 answers)
Closed 3 days ago.
Ive been trying these since yesterday but I couldnt make it.
I have 2 different Schemas, the User Schema and the Vital Signs Schema. The Vital Signs Schema is inside the userSchema as an array. What i need to do is to edit an specific vitalSigns object with an unique Id
Here is a postman example of the info i need to update
const userSchema = new mongoose.Schema({
email:{type: String, required: true},
password:[{type: String, required: true}],
confirmPassword:[{type: String, required: true}],
personalData: personalDataSchema,
vitalSigns: [vitalSignsSchema],
})
const vitalSignsSchema = new mongoose.Schema({
systolic: { type: 'Number', required: false },
diastolic: { type: 'Number', required: false },
temperature: { type: 'Number', required: false },
pulse: { type: 'Number', required: false },
rate: { type: 'Number', required: false },
blood: { type: 'Number', required: false },
date: { type: 'Date', required: false },
})
My route is catching both userId and vitalSigns because i tried to make it work with a lot of ways but i couldn't
Router.post('/user/:userId/vitalSignsEdit/:vitalId', async (req, res) => {
userServices.editVitalSigns(req.params.userId,req.params.vitalId, req.body)
})
Here is one example of a way that I tried to use to make it work but instead of updating the specific vitalSigns Id, it created another object of vitalSigns with the same Id that i tried to change.
User.findById(userId)
.then( user => {
if(user) {
if(user.vitalSigns.find( e => e._id === data._id)) {
User.updateOne({_id: userId}, { vitalSigns: [...user.vitalSigns, data] })
.then(e => console.log(e), i => console.log(i))
}
}
})
Hope someone could help me with these.
You could use $push
User.updateOne({_id: userId}, { $push: { vitalSigns: data } })
Use $ to access the array element matched.
db.collection.update({
"vitalSigns._id": "vs1"
},
{
$set: {
"vitalSigns.$.modified": true
}
})
Mongo Playground
Objective
I'm trying to pull the qr documents attached to each user (which have a maximum of six) and return both the documents and subdocuments from the my mongoDB using below controller function.
Function
const Qr = require('../models/qr');
const mongoose = require('mongoose');
module.exports.showActivations = async (req, res) => {
const qrCodes = await Qr.find({ user: req.params.id });
console.log(qrCodes);
};
Expected results
An example below shows how I expected the results to be returned by showing the subdocument details within 'redirect'
{
_id: new ObjectId("6317ad944f0f1db567b9608c"),
redirect: [
name: "Test",
url: "https://testurl.com"
qrcode: "data:image/png;base64,iVBORwasdf..."
],
user: new ObjectId("6310a2da50448e982336784a"),
__v: 0
}
Actual behavior
I am receiving [ [Object] ] instead of the redirect subdocuments with each document.
{
_id: new ObjectId("6317ad944f0f1db567b9608c"),
redirect: [ [Object] ],
user: new ObjectId("6310a2da50448e982336784a"),
__v: 0
}
qr.js (model)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const qrSchema = new Schema({
redirect: [{
name: String,
url: String,
qrcode: String,
}],
user: {
type: Schema.Types.ObjectId,
ref: 'User'
},
event: {
type: Schema.Types.ObjectId,
ref: 'Event'
},
});
module.exports = mongoose.model('Qr', qrSchema);
How do I yield the full qr document and subdocument details from my query?
I am currently trying to track which users like a certain post and based on that information there will be a 'liked' functionality on the post if the user already liked it. How would I go about this with these two current mongoose Schemas that I have?
User.js
const mongoose = require('mongoose')
const userSchema = mongoose.Schema({
username: String,
name: String,
email: String,
passwordHash: String,
dateOfBirth: Date,
location: String,
addictions: Array,
groups: Array,
biography: String,
posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
],
profileImageURL: String,
following: Number,
followers: Number
})
userSchema.set('toJSON', {
transform: (document, returnedObject) => {
returnedObject.id = returnedObject._id.toString()
delete returnedObject.__v
// the passwordHash should not be revealed
delete returnedObject.passwordHash
}
})
const User = mongoose.model('User', userSchema)
module.exports = User
post.js
const mongoose = require('mongoose')
const postSchema = new mongoose.Schema({
text: {
type: String,
required: true
},
images: Array,
video: String,
gif: String,
date: Date,
tags: String,
likes: Number,
comments: Number,
shares: Number,
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: String,
replies: {
type: mongoose.Schema.Types.ObjectId,
ref: "Replies"
},
})
const Post = mongoose.model('Post', postSchema)
module.exports = Post
Should i make a separate schema for likes to achieve this or can it be done with the two schemas i already have defined? Thanks!
This question was asked several times, but despite that, I wasn't able to solve my problem. In my mongoose collection, I store 30 users with the following mongoose schema. I want to implement a newsletter on my site, therefore I want to add the new field:
newsletter: {
type: Boolean,
default: true
},
My question is: How can I add newsletter false/true to every user?
I found that, but it didn't work.
User.updateMany({}, [{ $set: { newsletter: false }}])
My Schema:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
date: { type: Date, default: Date.now },
token: { type: String, required: true }
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
Adding to the schema "newsletter" does solve the problem for new users, but doesn't add the field to the already existing ones.
I am building a social media and one of the features I have is the ability to follow other users and have their posts show up on a home page, much like an Instagram feed. I have an endpoint that loops through all the users you are following and gets the post that are rated for your age, sorts them and puts them in an array.
router.get("/following", auth, async (req, res) => {
try {
const user = await User.findOne({ firebaseUID: req.authId });
const dob = dayjs(user.dob.toISOString().split("T")[0]);
const currentDate = dayjs(new Date().toISOString().split("T")[0]);
const age1 = currentDate.diff(dob, "year");
let posts = [];
for (let i = 0; i < user.following.length; i++) {
posts.push(
await Post.find({
userID: user.following[i].user,
age: { $lte: age1 },
})
);
}
posts = [].concat.apply([], posts);
posts = _.sortBy(posts, "date").reverse();
res.json(posts);
} catch (err) {
console.error(err.message);
res.status(500).json({ msg: "Server Error" });
}
});
The user schema looks like this
const UserSchema = new Schema({
firebaseUID: {
type: String,
required: true,
},
name: {
type: String,
required: true,
},
username: {
type: String,
required: true,
unique: true,
},
avatar: {
type: String,
},
dob: {
type: Date,
default: Date.now,
required: true,
},
slug: {
type: String,
},
following: [
//array of user IDs
{
user: {
type: Schema.Types.ObjectId,
ref: "users", //here so we know which lieks came from which users
},
},
],
followers: [
//array of user IDs
{
user: {
type: Schema.Types.ObjectId,
ref: "user", //here so we know which lieks came from which users
},
},
],
});
The problem is that I am trying to add infinite scroll pagination to the front end that will start by getting the first 15 posts and then get the next 15 and so on from endpoints that provide this.
What would the best way to do this be? For other routes, I have used .skip() and .limit(). I could split the array of posts up right before I send it as a response, but is there a way to do without getting all the posts as this would be taxing if you're following 100s of people with 1000s of posts.
I would need to loop through all the users you are following and get all their posts in line with your age rating but only get the first 15 sorted in date order from newest to oldest. Is there a mongoose function that I could use or would the best way be to split the array of posts?
Thank you.