【问题标题】:mongoose query to insert doc in not exist?用于插入文档的猫鼬查询不存在?
【发布时间】:2021-06-20 20:40:40
【问题描述】:

我的 MongoDB 集合如下:

[
    { x: "a", t: 1, s: 'old' },
    { x: "a", t: 3, s: 'old' },
    { x: "b", t: 1, s: 'old' },
    { x: "b", t: 4, s: 'old' }
]

我还有一个数组如下:

const list = [
    { x: "a", t: 1, s: 'new' },
    { x: "a", t: 2, s: 'new' },
    { x: "b", t: 2, s: 'new' },
    { x: "b", t: 3, s: 'new' },
]

现在我要插入

列表

将数组放入 mongo 集合中:

  • 如果要插入的项目存在于集合中,则不要插入它。
  • 如果要插入的项目存在于集合中,则插入它。

最终结果应该如下:

[
    { x: "a", t: 1, s: 'old' },
    { x: "a", t: 2, s: 'new' },
    { x: "a", t: 3, s: 'old' },
    { x: "b", t: 1, s: 'old' },
    { x: "b", t: 2, s: 'new' },
    { x: "b", t: 3, s: 'new' },
    { x: "b", t: 4, s: 'old' }
]

【问题讨论】:

    标签: mongodb mongoose aggregation-framework


    【解决方案1】:

    您可以使用带有upsert 选项的更新查询,

    const list = [
      { x: "a", t: 1, s: 'new' },
      { x: "a", t: 2, s: 'new' },
      { x: "b", t: 2, s: 'new' },
      { x: "b", t: 3, s: 'new' }
    ]
    

    第一个选项,循环执行每个查询,

    • 为更新查询创建函数
      • 查询以匹配xt 字段
      • $setOnInsert 仅当这是一个新文档时才设置字段
      • upsert: true 更新文档(如果已存在)
    • 循环list文档数组并调用更新查询函数
    async function updateQuery(doc){
      await YourModel.updateOne(
        { x: doc.x, t: doc.t },
        { $setOnInsert: doc },
        { upsert: true }
      );
    }
    
    list.forEach(function(doc) {
      updateQuery(doc);
    });
    

    Playground


    第二个选项,使用bulkWrite()方法在一个事务中执行所有更新查询,

    • updateQuery 函数创建 updateOne 查询
    • 循环list文档数组并调用updateQuery函数并构造更新查询数组
    • 调用bulkWrite查询函数
    function updateQuery(doc){
      return {
        updateOne: {
          filter: { x: doc.x, t: doc.t },
          update: { $setOnInsert: doc },
          upsert: true
        }
      };
    }
    
    let bulkWriteQuery = [];
    list.forEach(function(doc) {
      bulkWriteQuery.push(updateQuery(doc));
    });
    
    await YourModel.bulkWrite(bulkWriteQuery);
    

    【讨论】:

      【解决方案2】:
      • 您可以使用map 函数遍历列表。
      • 然后你可以使用猫鼬findOne来检查该项目是否已经存在于集合中。
      • 如果项目不存在save,则将其放入集合并继续迭代。 (该列表应该是您正在使用的 mongoose 模式的对象数组)
      list.map((item) => {
          if(!Collection.findOne({x: item.x, t: item.t})) {
              try {
                  await item.save();
              } catch(error) {
                  //handle the error
              }
          }
      });
      

      【讨论】:

        猜你喜欢
        • 2022-01-17
        • 1970-01-01
        • 2015-06-26
        • 1970-01-01
        • 2019-10-19
        • 1970-01-01
        • 2017-06-01
        • 1970-01-01
        • 2017-12-05
        相关资源
        最近更新 更多