I am creating something like fb... I want to show 3 comments only on home page... How to limit one field only... my schema is this:
const postSchema = new Schema({
admin: { type: Types.ObjectId, ref: 'users', required: true },
text: { type: String, required: true },
comments: [{
postId: { type: Types.ObjectId, ref: 'posts', required: true },
admin: { type: Types.ObjectId, ref: 'users', required: true },
comment: { type: String, required: true },
time: { type: Date, default: Date.now }
}],
createdAt: { type: Date, default: Date.now },
modified: { type: Boolean, default: false }
});
I have all comments in an array... I want to limit them... Please help
Try using $slice (projection) in MongoDB. The $slice operator controls the number of items of an array that a query returns.
If you want to fetch first 3 comments only then your query will be as below:
db.slice.find( {}, { comments: { $slice: 3 } } )
In case if you want last 3 comments then your query will be:
db.slice.find( {}, { comments: { $slice: -3 } } )
Related
Note
I went through other answers before posting this, so expecting help here.
Mongoose model :
const projectSchema = new mongoose.Schema({
user: { type: String, required: true },
profile: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Profile'
},
title: { type: String, required: true },
image: { type: String },
description: { type: String, required: true, minlength: 300, maxlength: 3000 },
comments: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Comment'
}],
state: { type: Boolean, default: true },
requests: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Request'
}],
createdAt: { type: Date, default: Date.now() }, // <== created at
Query:
const projects = await Project.find({
state: true
})
.limit(10)
.sort({ createdAt: -1 }) // <== have tried +1 and
// also ({ date: -1 }),
// it returns in ascending order
return res.send(projects || [])
I have tried +1 in place of 1 and also ({ date: -1 }), it sends in ascending order.
I want the latest projects to be on top of array.
I was able to resolve it.
I needed to sort before I put the limit.
const projects = await Project.find({
state: true
})
.sort({ createdAt: -1 }) // here
.limit(10)
return res.send(projects || [])
I want to list the users and search for comments in another collection using the same query.
That's my users Schema:
Schema({
cod: {
type: String,
require: true
},
name: {
type: String,
required: true
}
})
And that's my comments Schema:
Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'users'
},
post: {
type: Schema.Types.ObjectId,
ref: 'posts'
},
comment: {
type: String,
required: true
}
})
I want get some like this:
{
_id: 5eee97c18b83e338bcbfa8f9,
name: 'Cool Name',
cod: 'CN001',
comments: [{
_id: ObjectId(...)
post: ObjectId(...),
comment: 'comment 1'
},
{
_id: ObjectId(...)
post: ObjectId(...),
comment: 'comment 2'
}
]
}
is it possible?
Thank you!
you might need to change your schema to:
Users:
Schema({
cod: {
type: String,
require: true
},
name: {
type: String,
required: true
},
comments: {
type: Schema.Types.ObjectId,
ref: 'comments'
}
})
Comments:
Schema({
post: {
type: Schema.Types.ObjectId,
ref: 'posts'
},
comment: {
type: String,
required: true
},
user: { // in case you want to query comments and populate the user
type: Schema.Types.ObjectId,
ref: 'users'
}
})
Then query:
users.findById({'your user id here'})
.populate({path:'comments',select:['post','comment']})
.then((response)=>{
// do anything you want with the data here
})
I have a collection of jobs in MongoDB and in this collection there is a field in the documents named as appliedUser. I want to update this field when a new user applies for this job.So basically this field stores the id's of all the users who are applying for this job.
I am using findOneAndUpdate() function but not able to do it.
Job.findOneAndUpdate({ _id: req.params.id }, { $set: { appliedUser:
req.user.id } }, function(err, job) {
console.log(job);
})
and here is my Schema:
const jobSchema = new Schema({
date: { type: Date, default: Date() },
expirydate: { type: Date, required: true },
name: { type: String, required: true },
companydetails: { type: String, required: true },
address: { type: String, required: true },
role: { type: String, required: true },
city: { type: String, required: true },
minsalary: { type: Number, required: true },
maxsalary: { type: Number, required: true },
skills: { type: Array, required: true },
minex: { type: Number, required: true },
appliedUser: [{ type: Schema.Types.ObjectId, ref: 'users', unique:
true }],
user: { type: String, required: true }
})
The array of the document is not updating. I am not able to find the errors.
Look like what you need is $addToSet. Example:
Job.findOneAndUpdate({ _id: req.params.id }, { $addToSet: { appliedUser: req.user.id } }, function(err, job) {
console.log(job);
})
A list could have many items. I can easily retrieve all the items from a list but I'm having issues doing the opposite i.e retrieving all lists which contain an item
ItemSchema:
const ItemSchema = mongoose.Schema({
name: { type: String, required: true, min: 1 },
created_at: { type: Date, default: Date.now }
},{ toJSON: { virtuals: true }});
ListSchema:
const ListSchema = mongoose.Schema({
title: { type: String, required: true, max: 100 },
user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
description: { type: String, required: true },
items: [{
type: mongoose.Schema.Types.Mixed, ref: 'Item', quantity: 'String'
}],
completed: { type: Boolean, default: false },
date: { type: Date, default: Date.now },
});
Document:
"items": [
{
"_id": "5c6d74a98a3f532b4c1d2a23",
"quantity": "7"
}
],
How I populate: Item.findById(id).populate('lists'); but it returns empty array.
Any suggestions?
Haven't used MongoDB in a long time, but it doesn't seem you have "lists" key in your Item Schema to populate in the first place. Maybe you should add one or query the lists that have that item.
Consider this command:
WorkPlan.findOneAndUpdate({ _id: req.params.id }, updateObj, function(err) {
...
})
versus this:
WorkPlan.findOneAndUpdate({ _id: req.params.id }, { '$set': updateObj }, function(err) {
...
})
While developing my project, I was surprised to find out that the result of the first command is the same as the result of the second command: the updateObj is merged into the existing record in the database, even in the first case when it is supposed to replace it. Is this a bug in mongoose/mongodb or am I doing something wrong? how can I replace an object on update instead of merging it? I'm using mongoose 4.0.7.
Thanks.
==========
Update:
This is the actual WorkPlan schema definition:
workPlanSchema = mongoose.Schema({
planId: { type: String, required: true },
projectName: { type: String, required: true },
projectNumber: { type: String, required: false },
projectManagerName: { type: String, required: true },
clientPhoneNumber: { type: String, required: false },
clientEmail: { type: String, required: true },
projectEndShowDate: { type: Date, required: true },
segmentationsToDisplay: { type: [String], required: false },
areas: [
{
fatherArea: { type: mongoose.Schema.ObjectId, ref: 'Area' },
childAreas: [{ childId : { type: mongoose.Schema.ObjectId, ref: 'Area' }, status: { type: String, default: 'none' } }]
}
],
logoPositions: [
{
lat: { type: Number, required: true },
lng: { type: Number, required: true }
}
],
logoPath: { type: String, required: false },
}, { collection: 'workPlans' });
WorkPlan = mongoose.model('WorkPlan', workPlanSchema);
And this is an example of updateObj:
var updateObj = {
projectManagerName: projectManagerName,
clientEmail: clientEmail,
clientPhoneNumber: clientPhoneNumber,
segmentationsToDisplay: segmentationsToDisplay ? segmentationsToDisplay.split(',') : []
}
Therefore, when I'm NOT using the $set flag, I would expect the field projectNumber, for example, not to exist in the new record, yet I see it is still there.
Mongoose update treats all top level keys as $set operations (this is made more clear in the older docs: Mongoose 2.7.x update docs).
In order to get the behavior you want, you need to set the overwrite option to true:
WorkPlan.findOneAndUpdate({ _id: req.params.id }, updateObj, { overwrite: true }, function(err) {
...
})
See Mongoose Update documentation
In addition to the answer above:
[options.overwrite=false] «Boolean» By default, if you don't include
any update operators in doc, Mongoose will wrap doc in $set for you.
This prevents you from accidentally overwriting the document. This
option tells Mongoose to skip adding $set.
Link to docs: https://mongoosejs.com/docs/api.html#model_Model.update
This is works for me $set in Mongoose 5.10.1,
WorkPlan.where({ _id: req.params.id }).updateOne(updateObj);
Note:if you have inner object then give exact path of each key in updateObj
example:
"Document.data.age" = 19
ref: https://mongoosejs.com/docs/api.html#query_Query-set