I am trying to update a document with nested subdocuments, but i always retrieve the previus document.
i tried
{ returnOriginal: false }
but it is not working...
this is my code in nodejs
almacenCtrl.updateAlmacen = async (req, res) => {
almacen = await almacenModel.findOneAndUpdate(req.params.id, { $set: req.body }, { returnOriginal: false }, function (err, updated) {
res.json(updated)
})
}
what am i doing wrong?
//After update i check with mongoshell and the update was updated successfully
Use {new : true} as given below:
almacenCtrl.updateAlmacen = async (req, res) => {
almacen = await almacenModel.findOneAndUpdate(req.params.id, { $set: req.body }, { new: true }, function (err, updated) {
res.json(updated)
})
}
Related
I have a frontend in React and a backend in express and node.
From FE i am calling an API on the server:
const { data: autotaskItems } = useApiCall({
url: `api/endpoint`,
method: 'post',
payload: {
filter: {
_id: {
$in: ["id1","id2"],
},
},
},
});
on the server:
router.post('/config-items/find', async (req, res) => {
const { filter } = req.body
// ConfigItem.find({ ...filter })
// .then(result => {
// res.status(200).json({ success: true, data: result });
// })
ConfigItem.aggregate([
{ $match: { ...filter }
}])
.then(result => {
res.status(200).json({ success: true, data: result });
})
But this doesn't work. I have found that aggregate doesn't "support" automatic conversion of ObjectId to string. If I have used find() and spread filter like above this will work just fine. However, I do need to use aggregate as I have a couple of lookups there too.
Anyone can help, please?
Also, if possible i would like to keep structure with spreading the filter object for match
Thank you
As per #Martinez's answer, this was resolved by the following:
Nice and simple :-)
ConfigItem.aggregate([{
"$addFields": {
"_id": {
"$toString": "$_id"
}
}
},
//rest of the query
I am trying to update a field to the document with findByIdAndUpdate. The field I am trying to update is defined in the Bar Model. And I can also assure that req.body.bookId has a valid id.
Here's how my request looks,
app.patch("/foo", async (req, res) => {
try {
await validateId(req.body.bookId);
let doc = await Bar.findByIdAndUpdate(
req.body.bookId,
{ DateT: Date.now() },
{ new: true }
);
res.send(doc);
} catch (err) {
console.log(err);
}
});
Bar schema,
const mongoose = require("mongoose");
const barSchema = mongoose.Schema({
bookId: {
type: String,
unique: true,
},
DateT: {
type: Date,
default: null,
},
});
module.exports = mongoose.model("Bar", barSchema);
use updateOne, when you use async don't use .then() use try/catch
test it:
app.patch("/foo", async (req, res) => {
try {
let doc = await Bar.updateOne(
{ bookId : req.body.bookId },
{ DateT: Date.now() },
{ new: true }
);
res.send(doc);
} catch (error) {
console.log(error);
}
});
app.patch("/foo", async (req, res) => {
await Bar.findByIdAndUpdate(
req.body.bookId,
{ DateT: Date.now()},
(err, docs) => {
if (err) {
console.log(err);
} else {
res.send(docs);
}
}
);
});
I try to query MongoDB inside nodejs to get data for _id x I use
async function getTestData(id){
return new Promise((resolve, reject) => {
MongoClient.connect(uri, { useNewUrlParser: true, keepAlive: 1 }, function(err, client) {
const dbo = client.db("test");
var query = { _id: id };
dbo
.collection("smscripts")
.find(query)
.project({ 'data' : 1})
.toArray(function(err, items) {
err
? reject(err)
: resolve(items);
});
});
});
}
Query is
{ _id: '5dada7dfdca94dbaf65d9547' }
But I always get back an empty array. Anybody can help me out why the array is always empty? By the way, err is null. The id definitely exists.
in mongo db _id are prefix with ObjectId
so you need value first try this
id = ObjectId("507c7f79bcf86cd7994f6c0e")
and then compare it to ID.
hope it helps
First You need to import..
import { ObjectId } from "bson"
Then in Your code " var query = { _id: id }; " replace it with this..
var query = { '_id' : ObjectId(id) }
Then, in your code you are using .toArray() method. this would takes more time to
convert result to array. so you need to use await keyword before moving on.
Using Async-Await pattern this is very simple ..
const client = await MongoClient.connect(uri, { useNewUrlParser: true, keepAlive: 1 })
.catch(err => { console.log(err); });
if (!client) return;
try {
const dbo = client.db('test');
let collection = dbo.collection('smscripts');
let query = { '_id' : ObjectId(id) };
let projection = { 'data' : 1 } ;
let cursor = await collection.find(query, projection).toArray();
console.log(cursor);
return cursor;
} catch (err) {
console.log(err);
} finally {
client.close();
}
hope this works for you.
This Meteor client code does not update the documents found as expected. The console.log(res) prints '0' when there are documents to be updated.
Why and how to fix it? Thanks
MyCollection.find({
class: 'check-filter'
}).forEach((obj) => {
MyCollecction.update({
obj
}, {
$set: {
class: ''
}
}, (err, res) => {
if (!err) {
console.log(res);
}
});
});
Change your selector to use the object's _id:
MyCollection.find({ class: 'check-filter' }).forEach(obj => {
MyCollection.update(obj._id, { $set: { class: '' }}, (err, res) => {
if (!err) {
console.log(res);
}
});
});
Also you have a typo where you're trying to do MyCollecction.update instead of MyCollection.update
Using monk:
var doc =
yield new Promise(function (resolve, reject) {
tokens.findAndModify({
query: {
token: myTokenVar
},
remove: true,
new: false
}, function (err, res) {
if (err)
throw err;
resolve(res);
});
});
The following code above removes every field from the given document but however leaves the document with only the _id field left. It does not completely remove the document.
According the findAndModify source code, the opts object must be provided as a separate parameter. Please try it with the following codes
tokens.findAndModify(
{ query: {
token: myTokenVar
}},
{remove: true, 'new': false},
function (err, res) {
if (err)
console.log(err);
else
console.log(res);
});