I have two collections, campgrounds and reviews while deleting an review it stays in object array in campgrounds as an ObjectID ref and i can't find a way to delete them from there.
I tried
db.campgrounds.update({ title: "Ancient Hunting Camp" }, { $pull:{id:"60f8293044b0cc40c409f2f7"}})
db.campgrounds.update({ title: "Ancient Hunting Camp" }, { $pull: {reviews:{id:"60f8293044b0cc40c409f2f7"}}})
db.campgrounds.update({ title: "Ancient Hunting Camp" }, { $pullAll: {reviews:[]}},{multi:true})
db.campgrounds.update({ title: "Ancient Hunting Camp" }, { $pull: { reviews: {}}}, {multi:true})
db.campgrounds.update({ _id: "603d7a10f969af31484fb56e" }, { $pull: { reviews: "ratings"}})
db.campgrounds.update({ _id: "603d7a10f969af31484fb56e" }, { $pull: { reviews: ObjectId("60f976cd6132a91a20bd6679") }}
I've had these results
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
or
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
or
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 2,
"errmsg" : "Cannot apply $pull to a non-array value"
}
})`
Campground Schema
const CampgroundSchema = new Schema({
title: String,
image: String,
price: Number,
description: String,
location: String,
tel: Number,
website: String,
email: String,
reviews: [
{
type: Schema.Types.ObjectId,
ref: 'Review'
}
]
})
Related
I'm trying to update Sub-Sub Array item in MongoDB. I want to update the Comments(Comment field) inside the Slides array.
Slides--> Comments--> comment
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var AttachmentSchema = new Schema({
FileName: String,
InternalName: String,
FileType: String,
InternalName: String
});
mongoose.model('Attachment', AttachmentSchema);
var SessionSchema = new Schema({
SessionTitle: String,
Chairperson: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
StartDateTime: { type: Date, required: true },
Duration: Number,
Attendees: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
AcceptOrReject: {
Comment: String,
Reason: String,
CreatedDate: Date,
UserId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
Status: String
},
Slides: [{
Seq: Number,
Details: String,
attachement: AttachmentSchema,
TarasulLetterDetails:{
MailObjectId: String,
Description: String,
Subject: String,
TarasulLetterUrl: String
},
Comments: [{
Comment: String,
DateTime: Date,
UserId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
IsFromOnline : String
}],
SurfaceAttachement: [{
FileName: String,
InternalName: String,
FileType: String,
}]
}],
Status: String,
CreatedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
CreatedDate: { type: Date, required: true },
ModifiedDate: Date,
SentDate: Date,
Comments: [{
Comment: String,
DateTime: Date,
UserId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}],
Notifications: [{
UserId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
CreatedBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
AlertType: String,
AlertMessage: String,
DateTime: { type: Date, required: true },
IsAcknowledged: Boolean
}]
});
mongoose.model('Session', SessionSchema);
Below is the sample data.
> db.sessions.find({"_id": ObjectId('5af7bcdff107cb7a105243f5')}).pretty();
{
"_id" : ObjectId("5af7bcdff107cb7a105243f5"),
"SessionTitle" : "Project Status Meeting",
"Duration" : 60,
"StartDateTime" : ISODate("2018-05-15T05:15:00Z"),
"CreatedBy" : ObjectId("5aead4431a7ecc7230fb249a"),
"Status" : "APPROVED",
"CreatedDate" : ISODate("2018-05-13T04:19:43.050Z"),
"Notifications" : [
{
"IsAcknowledged" : false,
"DateTime" : ISODate("2018-05-14T09:15:23.385Z"),
"AlertMessage" : "Attendee updated",
"AlertType" : "Attendee",
"UserId" : ObjectId("5aead4a81a7ecc7230fb249c"),
"_id" : ObjectId("5af953ab67f3be54d4256f35")
},
],
"Comments" : [ ],
"Slides" : [
{
"Seq" : 1,
"Details" : "<p>Project Meeting</p>\n",
"_id" : ObjectId("5af7bcdff107cb7a105243f6"),
"Comments" : [
{
"_id" : ObjectId("5b45b854d217f62010fea8e7"),
"DateTime" : ISODate("2018-07-11T07:53:40.967Z"),
"IsFromOnline" : "3047",
"UserId" : ObjectId("5aead4431a7ecc7230fb249a"),
"Comment" : "test 123"
},
{
"_id" : ObjectId("5b45b89e7c32803a282e44db"),
"IsFromOnline" : "3043",
"DateTime" : ISODate("2018-07-11T07:58:22.648Z"),
"UserId" : ObjectId("5aead4431a7ecc7230fb249a"),
"Comment" : "new comments"
}
]
},
{
"Details" : "<p>second side</p>\n",
"Seq" : 2,
"_id" : ObjectId("5af7c843f107cb7a105243f7"),
"Comments" : [
{
"_id" : ObjectId("5b45b9bc569a4b284074fd08"),
"IsFromOnline" : "92179",
"DateTime" : ISODate("2018-07-11T08:03:01.851Z"),
"UserId" : ObjectId("5aead4431a7ecc7230fb249a"),
"Comment" : "test comments 123434343434343"
}
]
}
],
"Attendees" : [
ObjectId("5aead4a81a7ecc7230fb249c")
],
"Chairperson" : [
ObjectId("5aead4701a7ecc7230fb249b")
],
"__v" : 0,
"AcceptOrReject" : [
{
"Reason" : "More changes neened",
"Status" : "APPROVED",
"UserId" : ObjectId("5aead4701a7ecc7230fb249b"),
"CreatedDate" : ISODate("2018-05-14T09:15:23.385Z"),
"Comment" : "Will disucuss in next meeting"
}
]
}
For e.g i want to update Session "_id" : ObjectId("5af7bcdff107cb7a105243f5")
having Slides with Seq :1 and Comment from 'new comments' to 'Updated comments' with "IsFromOnline" : "3043".
i tried below and some other stuff, but it doesn't seem to work.
Session.update({
$and: [{
"_id": req.body.SessionId,"Slides.Seq": req.body.SeqNo
},
{
'Slides.Comments': {
$elemMatch: {
IsFromOnline: req.body.IsFromOnline
}
}
}
]
}, {
$set: {
'Slides.Comments.$.Comment': 'Updated comments'
}
})
Schema:
var educationSchema = new Schema({
schoolName: String,
startDate: Number,
endDate: Number,
degree: String,
major: String,
grade: String
});
var UserSchema = new Schema({
firstName: String,
lastName: String,
education: [educationSchema]
});
Update code:
User.findOneAndUpdate(
{"_id": req.user.id, "education._id": req.body.id},
{
"$set": {
"education.$": req.body
}
},
function(err, edu) {
}
);
Now, if the user only edits the schoolName on the UI the following happens:
Pre-save State:
{
"_id" : ObjectId("5878fb4f51ec530358fea907"),
"firstName" : "John",
"lastName" : "Doe",
"education" : [
{
"schoolName" : "ABC",
"startDate" : 1998,
"endDate" : 2005,
"degree" : "Bachelor’s Degree",
"major" : "CS",
"grade" : "3.5",
"_id" : ObjectId("5878fbb951ec530358fea909")
}
]
}
Post-save State:
"education" : [
{
"schoolName" : "XYZ"
}
]
Is $set not the right operator to use?
Updating education.$ updates the sub-document. If you want to update only the schoolName you must use education.$.schoolName.
Change your update code to:
User.findOneAndUpdate(
{"_id": req.user.id, "education._id": req.body.id},
{
"$set": {
"education.$.schoolName": req.body
}
},
function(err, edu) {
}
);
EDIT: (update any field sent through req.body)
const update = {};
Object.getOwnPropertyNames(req.body).forEach(key => {
update['education.$.' + key] = req.body[key];
});
User.findOneAndUpdate(
{"_id": req.user.id, "education._id": req.body.id},
{
"$set": update
},
function(err, edu) {
}
);
USER SCHEMA:
{
friends: [{
user_id: {type: mongoose.Schema.Types.ObjectId, required: true, ref: 'User'},
name: {type: String, required :true},
age: {type: Number, required: true}
}],
privacy_settings : {
visibility : {type : Number, enum: [0,1,2]},
permission : {type : Number, enum : [0,1]},
}
}
Above is a sub section of user schema. I want to filter out the friends whose user id's don't exist. Right now what I get is:
QUERY RESULT:
friends:
[ {},
{},
{},
{},
{},
{ user_id: 570f733f0e3fbfb7690b2384 },
{},
{},
{ user_id: 570f52b30e3fbfb7690b09f4 },
{},
{},
{},
{ user_id: 570f57490e3fbfb7690b0afe },
{ user_id: 571072576952b11f0320f324 } ],
The problem is I don't want these {}, just the data where user_id exists.
QUERY USED
user.findOne(
{_id: some_mongoose_id},
{'friends.userid privacy_settings'}, function(err,result){
console.log(err,result);
}
)
How can I go about this ?
Try This:
user.find({"friends.user_id" : {$ne : null}},function(err,data){
if(data){
//console.log(data);
}
});
Would you be kind to tell me is there any way to set limitation on array size while creating Mongoose schema. For example
var peopleSchema = new Schema({
name: {
type: String,
required: true,
default: true
},
/* here I want to have limit: no more than 10 friends.
Is it possible to define in schema?*/
friends: [{
type: Schema.Types.ObjectId,
ref: 'peopleModel'
}]
})
With a small tweak to your schema setup you can add a validate option:
var peopleSchema = new Schema({
name: {
type: String,
required: true,
default: true
},
friends: {
type: [{
type: Schema.Types.ObjectId,
ref: 'peopleModel'
}],
validate: [arrayLimit, '{PATH} exceeds the limit of 10']
}
});
function arrayLimit(val) {
return val.length <= 10;
}
starting from mongo 3.6 you can add validation for a collection at server end, each document inserted/updated will be validated against the validator $jsonSchema, only the valid gets inserted, validation error will be for invalid documents
db.createCollection("people", {
validator: {
$jsonSchema: {
bsonType: "object",
required: [ "name" ],
properties: {
name: {
bsonType: ["string"],
description: "must be a string"
},
friends: {
bsonType: ["array"],
items : { bsonType: ["string"] },
minItems: 0,
maxItems: 10,
description: "must be a array of string and max is 10"
}
}
}
}
});
collection
> db.people.find()
valid document
> db.people.insert({name: 'abc' , friends : ['1','2','3','4','5','6','7','8','9','10']})
WriteResult({ "nInserted" : 1 })
invalid document
> db.people.insert({name: 'def' , friends : ['1','2','3','4','5','6','7','8','9','10', '11']})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 121,
"errmsg" : "Document failed validation"
}
})
find
> db.people.find()
{ "_id" : ObjectId("5a9779b60546616d5377ec1c"), "name" : "abc", "friends" : [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" ] }
>
You can use $slice modifier at the time you push new friend id into your array
https://docs.mongodb.com/manual/reference/operator/update/slice/#up._S_slice
$push: {
friends: {
$each: [id],
$slice: -10
}
}
This is my schema and array limit on assignedToId via an external function.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const taskSchema = new Schema({
parentTask: {
trim: true,
type: Schema.Types.ObjectId,
ref: "task",
},
assignedToId: [{
trim: true,
type: Schema.Types.ObjectId,
ref: "Employees",
}],
createdBy: {
trim: true,
type: Schema.Types.ObjectId,
ref: "Employees",
required: [true, "User ID is required"]
},
createdByName: {
trim: true,
type: String,
required: [true, "Creater name is required"]
},
},
{
timestamps: true
});
// Validations for assignedTo employees' size
taskSchema.path('assignedToId').validate(function (value) {
console.log(value.length)
if (value.length > 10) {
throw new Error("Assigned person's size can't be greater than 10!");
}
});
const Tasks = mongoose.model("Tasks", taskSchema);
module.exports = Tasks;
I'm working on a commenting system with mongoose/n,
users can comment, and like in reddit, users should vote each comment up or down.
and i have the following comment scheme:
var commentSchema = new Schema({
text: String,
level: { type: Number, min: 0, max: 30, default: 0},
slug: String,
full_slug: String,
discussion_id: { type: Schema.ObjectId, ref: 'Uranus' },
parent_id: {type: Schema.ObjectId,ref: 'Comment'},
score: [{
upvote: {type: Number,min: 0,max: 9000},
downvote: {type: Number,min: 0,max: 9000},
voter: {type: Schema.ObjectId,ref: 'Account'}
}],
updated: { type: Date, default: Date.now },
created: { type: Date, default: Date.now },
author: { type: Schema.ObjectId, ref: 'Account' },
});
it works just fine, but i have no clue, how to update the score-array. it just doesn't work.
Here is the sample json-data i got:
{
"__v" : 0,
"_id" : ObjectId("52a0d4ff779edff16d000006"),
"author" : ObjectId("529dfdda6b2d7a450c000009"),
"created" : ISODate("2013-12-05T19:33:19.229Z"),
"discussion_id" : ObjectId("529f7b04cbab31cc3e000004"),
"full_slug" : "2013.12.05.19.33.19:e1CDx79g8",
"level" : 0,
"score" : [
{
"upvote" : 1,
"downvote" : 0,
"voter" : ObjectId("529dfdda6b2d7a450c000009"),
"_id" : ObjectId("52a0d4ff779edff16d000007")
},
{
"upvote" : 0,
"downvote" : 1,
"voter" : ObjectId("52a0d9883027a89d6e000002"),
"_id" : ObjectId("52a0d9903027a89d6e000004")
},
{
"upvote" : 0,
"downvote" : 1,
"voter" : ObjectId("52a0d99a3027a89d6e000005"),
"_id" : ObjectId("52a0d9a63027a89d6e000007")
}
],
"slug" : "e1CDx79g8",
"text" : "A Comment",
"updated" : ISODate("2013-12-05T19:33:19.229Z")
}
so, i just update the comment by
var query = {
'score.voter': mongoose.Types.ObjectId(String('52a0d9883027a89d6e000002'))
};
Comment.update( query, {$set: {"score.$.upvote": 10}} )
The problem is, that it's just not updating.
i know, there are a few other questions regarding this problem, but all solutions are not working for me. i hope someone can help me.
UPDATE:
Found the problem, Seems like you have to have a callback on the update function like this:
Comment.update( query, {$set: {"score.$.upvote": 10}}, { multi: false }, function(err,n){
console.log("affected rows:", n)
});