【问题标题】:Node.js + MongoDB: insert one and return the newly inserted documentNode.js + MongoDB:插入一个并返回新插入的文档
【发布时间】:2017-04-07 14:12:23
【问题描述】:

我想知道是否有一种方法可以一次性插入新文档并返回。

这是我目前正在使用的:

db.collection('mycollection').insertOne(options, function (error, response) {
    ...
});

【问题讨论】:

  • 退回新的是什么意思?您希望 insertOne 的响应是带有 _id 的文档吗?
  • 不,你不能。 insert 方法只返回文档插入成功的确认。你不能将两个动作合二为一。你必须在 insert() 之后再次触发 find()

标签: node.js mongodb


【解决方案1】:

UPDATE 2021:这种方法不再适用与 MongoDB 驱动程序 4.x. insertOne 的返回结果只包含一个 ID和确认标志:https://mongodb.github.io/node-mongodb-native/4.1/interfaces/InsertOneResult.html

通过此更改,无法完成所需的行为。应该执行另一个 DB 请求,或者将返回的 insertId 和原始对象数据结合起来。


response 结果包含有关命令是否成功以及插入的记录数的信息。

如果要返回插入的数据,可以试试response.ops,例如:

db.collection('mycollection').insertOne(doc, function (error, response) {
    if(error) {
        console.log('Error occurred while inserting');
       // return 
    } else {
       console.log('inserted record', response.ops[0]);
      // return 
    }
});

insertOne的官方文档:

http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#insertOne

callback 类型:

http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#~insertOneWriteOpCallback

result 类型:

http://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#~insertOneWriteOpResult

【讨论】:

  • 成功了!但是,当我执行console.log(response) 时,ops 却没有出现,这有点奇怪!
  • 它与评估值的时间有关。
  • 谢谢!它记录在mongodb 驱动程序的node 部分insert a document 的github 页面上。来自文档:ops - Contains the documents inserted with added _id fields.
  • 什么奇怪的是有时文档建议不推荐使用的方法,然后终端给出警告,似乎 stackoverflow 有更多更新的代码
  • 这个答案是正确的,虽然我不确定为什么ops 是一个数组,而该方法应该只插入一个文档。
【解决方案2】:

以下代码适用于我,在 MongoDB 版本 2.2.33 中。

db.collection("sample_collection").insertOne({
   field1: "abcde"
}, (err, result) => {
   if(err) console.log(err);
   else console.log(result.ops[0].field1)
}

【讨论】:

    【解决方案3】:

    对于那些使用 MongoDB 驱动程序 4.x 的人,我找到了findOneAndUpdate 的解决方法:

          const toInsert = {
            _id: mongo.ObjectId(),
            someField: 'hello',
            someOtherField: 'world'
          };
          const options = { upsert: true, returnDocument: 'after' };
          const { value: document } = await db.collection.findOneAndUpdate(
            toInsert,
            { $set: {} },
            options
          );
    

    注意toInsert 中的_id 是新生成的ObjectId

    更新是空的 ({ $set: {} }) 并且什么都不做,因为我们不需要更新,我们只想更新我们的文档。仍然需要它,因为更新不能是 null 或空对象。

    由于returnDocument 选项,新创建的文档将作为结果中的值返回。


    为了避免空更新,另一种解决方案是使用$setOnInsert

          const toInsert = { someField: 'hello', someOtherField: 'world' };
          const options = { upsert: true, returnDocument: 'after' };
          const { value: document } = await db.collection.findOneAndUpdate(
            { _id: mongo.ObjectId() },
            { $setOnInsert: toInsert },
            options
          );
    

    【讨论】:

      【解决方案4】:

      您可以使用mongoose 来执行此操作。使用save 方法,您可以插入一个文档并在成功时返回它。以下是来自mongoose documentation 的示例:

      product.save(function (err, product, numAffected) {
        if (err) {
          // Handle error...
        } else {
          // Do something with the returned document...
        }
      })
      

      【讨论】:

      • 如果文档已经存在,它将返回它。不是新的
      • 此方法不再适用于 MongoDB 驱动程序 4.x。 insertOne 的返回只包含一个 ID 和确认标志
      【解决方案5】:

      发布此内容可能对某人有所帮助。您可以像这样找到更新的对象:

      await req.db
          .collection('users')
          .insertOne({ email, password: hashedPassword, name  })
          .then(({ ops }) => ops[0]);
      

      【讨论】:

        【解决方案6】:

        您可以使用mongojs 来执行此操作。

        db.collection('mycollection').save(doc, function(error, response){
          // response has _id
        })
        

        【讨论】:

          【解决方案7】:

          试试这个

          try {
              let collection = db.collection('collection_name'); let { ops: inserted } = 
              await collection.insertOne({ data: object });
              // can access array of inserted record like :
              console.log(inserted)
           } catch (error) {
              // log errors
           }
          

          【讨论】:

            【解决方案8】:

            2021 年更新:此方法不再适用于 MongoDB 驱动程序 4.x。 insertOne 的返回只包含一个 ID 和确认标志

            我想仍然使用 .then() 通过插入来解决,所以我最终将所有内容都包装在它自己的承诺中。

             return new Promise((resolve, reject) => {
                 db.collection('entries').insertOne({ entry }, (err, res) => {
                 if (err) {
                   console.log('error', err);
                   reject(null);
                 } else {
                   resolve(res.ops[0]);
                 }
               });
             });
            

            那我就可以了

             insertEntry({}).then(entry=>{})
            

            【讨论】:

            • Node 驱动程序 4.x 不再支持此功能
            猜你喜欢
            • 2021-10-03
            • 1970-01-01
            • 1970-01-01
            • 2023-04-05
            • 1970-01-01
            • 2016-04-05
            • 2020-09-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多