简体   繁体   中英

findOneAndUpdate provides only a partial update

I'm trying to update a database document, depending on user input, and whether it exists or not (and create it if not). The user can retrieve stock price of a company, and like it once.

 async function run() { var price = await getPrice(query.stock); if (!price) { return res.json({ stockData: { error: "stock not found" } }); } if (!Array.isArray(query.stock)) { MongoClient.connect(CONNECTION_STRING, function(err, client) { var db = client.db("mydb"); db.collection("stock").findOne({ stock: query.stock.toUpperCase() }, (err, doc) => { if (err) throw err; if (!doc && !query.like) { return res.send({ stockData: { stock: query.stock.toUpperCase(), price: price, likes: 0 } }); } if (doc && !query.like) { return res.send({ stockData: { stock: query.stock.toUpperCase(), price: price, likes: doc.likes } }); } if (!doc && query.like) { db.collection("stock").insertOne({ stock: query.stock.toUpperCase(), likes: 1, ips: [req.ip] }); return res.send({ stockData: { stock: query.stock.toUpperCase(), price: price, likes: 1 } }); } if (doc && query.like) { if (!doc.ips.includes(req.ip)) { db.collection("stock").findOneAndUpdate( { stock: query.stock.toUpperCase() }, { $inc: { likes: 1 } }, { $addToSet: { ips: req.ip } }, { returnOriginal: false }, (err, updoc) => { if (err) throw err; return res.send("test"); } ); } return res.send({ stockData: { stock: query.stock.toUpperCase(), price: price, likes: doc.likes } }); } }); }); } }

My issue is with the findOneAndUpdate operation. It is supposed to increase the number of likes and add user's ip to the array, so that they can't like it again. It does the former as it should, but the array remains unchanged. In fact, other manipulations with it bear no fruit either. What's more, the program never progresses to the callback, doesn't return "test" and doesn't allow me to access the update document updoc.

As per the documentation , This is how you should be updating the document

 db.collection.findOneAndUpdate(
   <filter>,
   <update>,
   {
     projection: <document>,
     sort: <document>,
     maxTimeMS: <number>,
     upsert: <boolean>,
     returnNewDocument: <boolean>
   }
)

So all the Update stuff should be in the second parameter, so update your code like this

db.collection("stock").findOneAndUpdate(
              { stock: query.stock.toUpperCase() },
              { $inc: { likes: 1 } , $addToSet: { ips: req.ip } },
              { returnNewDocument: false },
              (err, updoc) => {
                if (err) throw err;
                return res.send("test");
              }
            );

As I don't know about returnOriginal but I do know about the property returnNewDocument which by default is false , but if you want to mention it explicitly it's totally up to you.

Model.findOneAndUpdate({...query}, {...operations}, { new: true })

我认为这是针对猫鼬的,但您也可以使用returnNewDocument: true

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM