The following query updated the collection and increments the field count
. I want to send the updated count
as a response without making another api call.
The variable usage
does not project the values.
handler.put(async (req, res) => {
console.log("in backend api to update geo count")
await req.db.collection('analytics').updateOne(
{
_id: getDateMonYear(new Date(), "mmddyyyy"),
type: "Geo",
},
{
$inc: { "count": 1},
},
{upsert: true},
);
res.status(200).send({usage});
});
Expected result sent back as json response:
{
"_id": "Sept292022",
"type": "Geo",
"count": 162
}
Edit, I made it work by hitting the collection again like below but is there a way to just return in the update above?
const usage = await req.db.collection('analytics')
.findOne(
{
_id: getDateMonYear(new Date(), "mmddyyyy"),
}
);
res.json({status:200, usage});
});
CodePudding user response:
Use {returnNewDocument: true}
in the options, to get the updated document in the response:
await req.db.collection('analytics').updateOne(
{
_id: getDateMonYear(new Date(), "mmddyyyy"),
type: "Geo",
},
{
$inc: { "count": 1},
},
{upsert: true, returnNewDocument: true}
);
CodePudding user response:
Based on the edits it looks like things are moving in the right direction. I'm a bit confused by the comments, so perhaps this answer will help clarify things.
My understanding of your current server code is that it looks like the following now:
handler.put(async (req, res) => {
console.log("in backend api to update geo count")
await req.db.collection('analytics').updateOne(
{
_id: getDateMonYear(new Date(), "mmddyyyy"),
type: "Geo",
},
{
$inc: { "count": 1},
},
{upsert: true},
);
const usage = await req.db.collection('analytics')
.findOne(
{
_id: getDateMonYear(new Date(), "mmddyyyy"),
}
);
res.status(200).send({usage});
});
Was the problem originally that the usage
object that the client was receiving was not the actual document that was updated?
If both of these things are correct, then using findAndModify()
is the correct approach here. The problem with the original code is that the output of updateOne()
is a summary of the operation as opposed to the document itself. On the other hand, the findAndModify()
operation returns the document that was modified (either before or after). Also, this operation has been around for many years, introduced long before 4.4
.
So I think your code should look something like the following to achieve your desired result:
handler.put(async (req, res) => {
console.log("in backend api to update geo count")
const usage = await req.db.collection('analytics').findAndModify({
query: {
_id: getDateMonYear(new Date(), "mmddyyyy"),
type: "Geo",
},
update: {
$inc: { "count": 1},
},
upsert: true,
});
res.status(200).send({usage});
});
If this doesn't solve your problem, it would also be helpful to confirm what driver and driver version you are using.