Mongo的更新许多带有重命名的字段不会更新

时间:2019-07-26 01:27:09

标签: node.js mongodb mongoose

说明

在某些字段上与updateMany一起使用时,MongoDB的$rename方法不会更新任何文档。

示例

我尝试重命名字段blog.blog_ttileblog.blog_cotnet。我检查了错别字,没有错。

Example model:

User: {
  name,
  email,
  blog: {
    blog_ttile,
    blog_cotnet
  }
}

代码:

const mongoose = require('mongoose');

const User = mongoose.model('User');

const nameChanges = {
  "blog.blog_ttile": 'blog.title',
  'blog.blog_cotnet': 'blog.content',
};

async function performNameChanges() {
  try {
    const updatedDocuments = await User.updateMany({}, { $rename: nameChanges }); 

    console.log({ updatedDocuments });
  } catch(err) {
    console.error(err);
  }
}

返回:

{ updatedDocuments: { ok: 0, n: 0, nModified: 0 } }

其他详细信息

某些字段被正确识别。让我们在上面的示例中说email。但是,当我尝试更新更新的名称时,它将不再起作用。有趣的是,它仍然可以检测到原始名称。

示例

email重命名为personal_email是可行的。之后没有将personal_email重命名为email并返回{ ok: 0, n: 0, nModified: 0 }。再次在email上调用重命名将返回{ n: <total_records>, nModified: 0, ok: 1 },尽管现在没有文档包含email

可能是什么原因造成的?

注意: 此问题适用于不带Mongoose的db.getCollection("User").updateMany而不是User.updateMany的MongoDB

3 个答案:

答案 0 :(得分:2)

我尝试在MongoDB中做同样的事情。它按预期工作。在您的情况下,我怀疑猫鼬模式是造成这种怪异行为的原因。猫鼬模式必须具有您要重命名的字段。如果该字段不存在,则返回nModified0。该模式将需要同时具有旧名称和新名称。旧版本允许迁移,新版本则允许代码中的新逻辑。

您的返回结果是:

{ updatedDocuments: { ok: 0, n: 0, nModified: 0 } }

这怎么可能? n = 0?查询{}。仅当您的集合中没有元素时才有可能。 n表示匹配的计数,它必须等于集合中的记录总数。

  

将电子邮件重命名为personal_email可以

在第一次更新之前,您的架构是可以的。但是在重命名(第一次更新)之后,您应该将架构更新为:

User: {
  name,
  personal_email,
  blog: {
    blog_tile,
    blog_contnet
  }
}

在运行第二个更新之前(重新命名为电子邮件)。

答案 1 :(得分:0)

正如在另一个答案中所说,这是因为您的猫鼬架构不包含您要重命名的字段。

在迁移发生时,您还可以在选项中指定 strict: false,而不是保留旧字段,并且 mongoose 不会丢弃未知路径:

const mongoose = require('mongoose');

const User = mongoose.model('User');

const nameChanges = {
  "blog.blog_ttile": 'blog.title',
  'blog.blog_cotnet': 'blog.content',
};

async function performNameChanges() {
  try {
    const updatedDocuments = await User.updateMany(
      {},
      { $rename: nameChanges },
      {
        // Strict allows to update keys that do not exist anymore in the schema
        strict: false,
      }
    ).exec();

    console.log({ updatedDocuments });
  } catch(err) {
    console.error(err);
  }
}

答案 2 :(得分:0)

这样使用谢谢


import { connect } from '../database';

export const renameFileds = async () => {
  const db = connect();
  //let userlist = await db.UserModel.find();
  const updatedDocuments = await db.UserModel.updateMany(
    {},
    { $rename: { image: 'picture' } },
    {
      // Strict allows to update keys that do not exist anymore in the schema
      strict: false,
    }
  ).exec();

  console.log({ updatedDocuments });
};
renameFileds();