mongoose $pull get nModified: 0 - node.js

After spending the whole day with that problem... i need help.
Node v12.14.1
mongoose v5.8.9
mongoDB v4.2.1
So everything is up to date.
I tried many ways, but this is how it should work:
model.updateOne({_id:model_id},{$pull: {videos: {_id:video_id},{multi:true})
but then i get
{ n: 1, nModified: 0, ok: 1 }
So, it get found, no errors but it dosent remove/modify the object.
Cant figure out what should be wrong.

So from your query, I am assuming this is what your document looks like:
{
_id: "<some uuid>",
videos: [
{
_id: "<some uuid>"
},
{... n}
]
}
If that is the case, your update query looks good, and maybe you need to consider the video_id input.
Could you try the equivalent find?:
model.find({_id:model_id, 'team._id': video_id})

Sometimes...
Sometimes the mistake took place way before we reach this line of code...
It was hard to find cause in terminal output and also in compass everything looks fine.
But, at that moment where i save the video and update the user to just have video id, title and slug also in the user collection, i did this:
$push: {
videos: [{
_id: data._id,
title: data.title,
slug: data.slug
}]
}
Yes, i pushed an empty array containing an object into an array. But like i said, the output and also .find() was like everything is okay.
After i removed the [] brackets and tested a new data set, $pull works fine.
Guess this was my hardest bug... hardest bug till now!
Thanks for your helps!

Related

MongoDB Realm NodeJS SDK $project syntax?

I'm trying to do a simple query where some collection data is returned. I want to filter out the _id field in the results.
From my understanding (based on the documentation) the syntax to do so should look like this:
myCollection.findOne(
{ name: hostName },
{ $project: { _id: 0 } }
)
However when I do this the filter has not been applied, e.g.:
{
_id: XXXXXXXXXXXXXXXXXXXX,
name: 'the name',
...
}
Can anybody point me in the right direction?
There are other options for $project. Below one provides the data without _id
myCollection.findOne({ name: hostName }, { '_id': 0 },(err,res)
In case anyone else comes across this, it turns out that the documentation is inaccurate and does not reflect the current state of the SDK.
For reference, see this GitHub Issue where it was confirmed by a Realm dev: https://github.com/realm/realm-js/issues/3275

Mongoose's findByIdAndUpdate not changing database's state

I have a strange problem. I want to update a document in my MongoDB with the mongoose.findByIdAndUpdate method, but it seems not to be working. The code is:
Device.findByIdAndUpdate(
req.params.id,
{ $set: { power: power } },
{ new: true },
(err, device) => { ... }
I get no error, but the device returned in the callback does not have the updated value. At first I thought maybe it was some sort of problem with the { new: true } option that tells mongoose to return the updated document, but then I checked the database, and the value there also has not been updated.
I also tried replacing findByIdAndUpdate with update function, but the results are the same - the db is not getting updated.
If it changes anything I use mongoose.update() function in other places and it works fine. I also tried the 'classical' way of updating the value here - meaning I used findOne function and then changed returned document's power field value and saved it and it also worked fine.
I will be really gratefull for any advice on fixing this. Thank you!

How to insert an Object into MongoDB

So I have an object using a dictionary to store products that a user has added to the cart in a shopping cart application. I am taking is object and attempting to insert into mongoDB with zero luck.
The piece of data I am attempting to insert looks like this:
products: '{"rJUg4uiGl":{"productPrice":"78.34","count":2},"BJ_7VOiGg":{"productPrice":"3","count":2}}' }
My process of attempting to insert it into mongoDB looks like this:
db.orders.insert("products":{"rJUg4uiGl":{"productPrice":"78.34","count":2},"BJ_7VOiGg":{"productPrice":"3","count":2}});
Currently with this approach I get the following error:
2016-12-15T18:11:43.862-0500 E QUERY [thread1] SyntaxError: missing ) after argument list #(shell):1:27
Which is implying there is some sort of a formatting issue with inserting it. I have moved quotation marks and parenthesis around plenty, simply to either get the above error, or a ... response from mongoDB implying that it is waiting for me to do something more to fix what exactly is causing an error.
Any chance anyone could help give some guidance in the best way to store this object in mongoDB?
My true question feels that it should have been in regards to the mongoose schema that would be used in order to store this data format. I hoped that getting how to initially insert it into mongodb was going to be enough but the way the data is being saved has me a bit confused. I know this is a bit of an awful question but could I get any assistance with setting up my schema for this as well?
"products" : {
"rJUg4uiGl" : {
"productPrice" : "78.34",
"count" : 2
},
"BJ_7VOiGg" : {
"productPrice" : "3",
"count" : 2
}
}
This is what the data looks like when it is stored in mongo. I think what is confusing me on how to set up is the "rJUg4uiGl" portion of the data. I am un-sure of how exactly that is suppose to look in mongoose schema. Here are a few of my rather poor attempts:
products: {
productId: {
productPrice: Number,
count: Number
}
}
Above simply doesn't store anything in the database
products: {
productId: [{
productPrice: Number,
count: Number
}]
}
Above gives:
"products" : {
"productId" : [ ]
}
Again, I know that this is quite specific but any help at all would be extremely appreciated.
Need to wrap your insert data in {}
db.orders.insert({"products":{"rJUg4uiGl":{"productPrice":"78.34","count":2},"BJ_7VOiGg":{"productPrice":"3","count":2}}});

Mongoose Aggregate doesn't work without find() first

Not sure exactly what's going on, but I have a Model#aggregate() call that works when it's preceded by a Model#find(), but not otherwise. This is the code I'm using (with dummy properties, Thing being my model object):
var query = { my_ids: { $in: _.pluck(this.related_ids, 'my_ids') } };
// This Thing.find is never executed and shouldn't ever be needed.
Thing.find(query);
Thing.aggregate([
{ $match: query },
{ $group: { _id: null, "amount": { "$sum": "$amount" } } },
]).exec(function(error, result) {
// blah blah blah
});
When run as-is, it works as expected - the callback's result is [{ _id: null, amount: <some number> }] as expected. However, if the Thing.find(query); is commented out, it is just a blank array [].
I know Thing.find() is returning a Query object and might be setting some state things in the background, which may be letting the aggregate() call finish, but it also doesn't work when the query is executed (which I'd assume would reset those state variables). I'm cool with leaving the Thing.find(query) call in to make it work for now, but it does make my eye twitch a little bit. Any thoughts?
Found it, bit of a silly solution, but it's good to have answers to similar problems up on SO.
The problem: race conditions. The second I saw "this thing seems to affect an unrelated thing" while using Node.js, that's where my mind should have gone. This code happens immediately after some code where the objects are populated in the database (this is in a test), and there were some validation errors happening that weren't being caught. In any case, the objects weren't done being saved to the database, so with the slight delay of the Thing.find() call, it was delaying the aggregation until they were saved.

Mongoose: Using addToSet with ObjectIds Results in Orphan Id

I am having a rather interesting problem using mongoDB's $addToSet to an array full of ObjectIds.
In my mongoose schema ("Happening"), I declare an array of ObjecIds called "expected", to be used by .populate().
expected: [{type: Schema.Types.ObjectId, ref: "User" }]
... which works nicely everywhere I use it. So far so good.
I then attempt to update the Happening.expected array using $addToSet as outlined here:
http://docs.mongodb.org/manual/reference/operator/addToSet/
like so:
app.get("/happening/yamobethere/:id", ensureLoggedIn("/login"),
function (req, res) {
// userId is the mongo ObjectId of the user record
var userId = req.session.user.id,
eventId = req.params.id;
models.Happening.update(
{_id: eventId}, {
$addToSet: {expected: userId}
},
function(err, updated){
if (err) {
res.json({"error": err});
}
res.json({"updated": updated});
});
});
... which always yields:
{updated: 1}
Now the docs lead me to expect the actual userId that I passed in, so the "1" is a bit odd. I expected it to be a fail, and in light of the weirdness that happens next, it appears to be a mongodb error of some sort percolating it's way back to me as results.
The weirdness is, when I check my database, I see that indeed a new ObjectId has been added: just not the one I passed in.
"expected" : [
ObjectId("51cb18623ade2b9f1e000004"),
ObjectId("51cdb7c12f0e58bdb3000001")
],
becomes
"expected" : [
ObjectId("51cb18623ade2b9f1e000004"),
ObjectId("51cdb7c12f0e58bdb3000001"),
ObjectId("51cdb80e09612bfab3000002")
],
The new ObjectId does not appear in any of my collections. It appears to be an orphan, but I'm a mongo noob, so I may be full of compost on this.
I did attempt to cast the userId as an ObjectId:
$addToSet: {expected: mongoose.Types.ObjectId.fromString(userId)}
but that changed nothing, and really should not be necessary, since the schema should handle it.
I'd really rather not resort to downloading the entire object, appending the value to the "expected" array, then sending the whole schmear back for an update.
Any help appreciated, folks. Thanks!
Update:
A colleague suggested the following technique:
var addMe = {$addToSet: {expected: userId}};
models.Happening.findByIdAndUpdate(eventId, addMe, function(err, me) {
if (err) {
return json(err);
}
res.json(200, me);
});
... which is a bit of an improvement, since it actually returns an object for me to inspect. Unfortunately, it also results in orphaned ObjecIds appearing in the array, rather than the existing userId value I specified.
Thanks again!
It appears that my passport strategy is returning the ObjectID of the rejected attempted creation of a new user in the db via data from oauth. So, the code is fine, my data is garbage.
Never trust anything, and be prepared to look like a boob. :-)
Thanks for the clarification on my return values JohnnyHK.

Resources