Cannot update a property in an embedded Array in mongoose - node.js

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)
});

Related

How to remove an Array of ObjectID's in mongodb?

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'
}
]
})

Update Sub Sub Array item in MongoDB

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'
}
})

mongodb: expires not working

In mongoose 5.0.6, I'm hoping this schema to expire documents 1min after creation:
const InvitationTokenSchema = new Schema(
{
token: { type: String, required: true },
createdAt: { type: Date, default: Date.now, expires: '1m' },
userId: { type: Schema.Types.ObjectId, ref: 'User' },
},
{
usePushEach: true,
},
);
However it simply doesn't work - all documents just persists in mongo, not being removed.
In mongo shell, getIndexes() shows the following:
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "mydb.invitationtokens"
},
{
"v" : 2,
"key" : {
"createdAt" : 1
},
"name" : "createdAt_1",
"ns" : "mydb.invitationtokens",
"expireAfterSeconds" : 60,
"background" : true
}
]
What possibly could be the reason?
As I see you code, its right.
Also, the value should be String and you can use '1m' as well.
You need to update the mongoose to the latest version.
Use: npm update mongoose
For more details search for "expires" here: http://mongoosejs.com/docs/api.html

Using Mongoose to access values in an array

I am trying to write a project app that monitors medical data implemented using a MEAN stack. I intend to simulate the data by sending a 'vitalsTick' about every second. These are stored as an array of subdocuments in the patient document.
var mongoose = require('mongoose');
var vitalsTickSchema = new mongoose.Schema({
time : {type: Number, min : -299, max: 300, required: true},
pulse : {type: Number, required:false},
rhythm : {type: String, required: false},
resp : {type: Number, required: false},
spo2 : {type: Number, required: true}
});
var VitalsTick = mongoose.model('vitalsTick', vitalsTickSchema, 'vitalsTick');
module.exports = VitalsTick;
and
var vitalsTickSchema = mongoose.model('vitalsTick').schema;
var patientRecordSchema = new mongoose.Schema({
name : {type: String, required: true},
mrn : {type: Number, required: true},
dob : {type: Date, required: false},
address : {type: String, required: false},
mhx : {type: [{history : {type: String, required: false}}]},
vitalTicks : [vitalsTickSchema]
});
var PatientRecord = mongoose.model('patientrecord', patientRecordSchema, 'patients');
module.exports = PatientRecord;
I have written some python to generate test data in json that validates using jsonlint and then imported to mongodb. Before moving to the next step of development, I want to ensure the schemas work as planned. Using Mongo:
> db.patients.find()
{ "_id" : ObjectId("59c2fc69b9e18eb6ad18c063"), "name" : "Testie
McTestface", "mrn" : "11111111", "dob" : "", "address" : "", "mhx" : [ { } ],
"vitalTicks" : [ { "time" : 0, "pulse" : 75, "rhythm" : "sinus",
"rr" : 20, "SpO2" : 96 }, ... ] }
My problem is this:
> db.patients.find({vitalTicks: {time : {$eq :0}}},{'vitalTicks.$':1})
>
As far as I can tell should return
{ "_id" : ObjectId("59c2fc69b9e18eb6ad18c063"), "vitalTicks" : [ {
"time" : 0, "pulse" : 75, "rhythm" : "sinus",
"rr" : 20, "SpO2" : 96 } ] }
But it returns nothing.
Cheers.
No, actually it is an array of embedded documents, the following query makes the job:
db.patients.find({"vitalTicks.time" : 0}, {"vitalTicks.$":1})
Hope this helps.

mongoose: update field, push object in array [duplicate]

This question already has answers here:
Stop Mongoose from creating _id property for sub-document array items
(7 answers)
Closed 7 years ago.
I would like to add an element in an array in a mongo database:
db.keypairs.update( {pubkey: "1234567890"}, { $push: {listTxId: {txHash: "yyy", spent: false} } } )
The result is perfect:
listTxId" : [ { "txHash" : "xxx", "spent" : true },{ "txHash" : "yyy", "spent" : false } ]
Now I would like to do the same with node.js and mongoose
var res = wait.forMethod(Keypair,'update', {pubkey: "1234567890"}, { $push: { "listTxId": {"txHash":"zzz", "spent":false} } } );
Keypair is my node.js model for the mongoose collection:
var Keypair = require('./app/models/Keypair');
and wait.forMethod comes from a node module:
var wait = require('wait.for');
In the result, I have this "_id" element :
{ "txHash" : "zzz", "spent" : false, "_id" : ObjectId("56561571fea5d9a10a5771fd") }
QUESTION: where this ObjectId come from ? How can I get rid of it ?
UPDATE: mongoose schema:
var keypairSchema = mongoose.Schema({
userId : { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
pubkey : String,
privkeyWIF : String, // temp
balance : Number,
listTxId : [{
txHash : String,
spent : Boolean
}],
walletId : { type: mongoose.Schema.Types.ObjectId, ref: 'Wallet' },
description : { type: String, maxlength: 40 },
comments : String,
isMasterKey : { type: Boolean, default: false },
date : Date
});
Mongoose will put ids in your subdocument arrays. listTxId is a subdocument array. You can add _id: false to your schema to prevent this:
var keypairSchema = mongoose.Schema({
userId : { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
pubkey : String,
privkeyWIF : String, // temp
balance : Number,
listTxId : [{
_id: false,
txHash : String,
spent : Boolean
}],
walletId : { type: mongoose.Schema.Types.ObjectId, ref: 'Wallet' },
description : { type: String, maxlength: 40 },
comments : String,
isMasterKey : { type: Boolean, default: false },
date : Date
});

Resources