3

我在 mongodatabase 中有一个文档

user:{
    name:'bruce',
    surname:'wayne',
    job:'batman',
    email:'onlyifdanger@batman.com',
}

所以当用户更新信息时,我必须:

  1. 如果用户存在,则查询数据库
  2. 如果存在获取数据库的值
  3. 将数据库的值与用户发送的表单值进行比较
  4. 如果数据库中的值相等,则丢弃该操作
  5. 如果数据库中的值不同,则使用表单值更新值
  6. 关闭数据库并发送.response

所以在这种情况下,如果用户发送这个:

form.newUserInfo:{
    name:'bruce albert',
    surname:'wayne',
    job:'batman only at night',
    email:'onlyifdanger@batman.com',
}

只需更新姓名和工作。

有什么方法可以在不到 6 步的时间内做到这一点?我正在使用 nodejs v0.10、mongodb 2.2.3、expressjs 和 mongoskin v0.5

4

2 回答 2

2

您可能已经从其他评论/答案中获得了所需的信息。但这是一种非常强大的插入数据的方法。

使用 $findAndModify 你可以控制乐观并发和 upsert。

如果您愿意,您可以找到差异,但如果您可以确定文档与用户打开它时的文档相同,您将使用 findAndModify 自动更新文档,其中值与加载时的文档相同.

此命令中的更新部分会更新所有值,但如果您愿意,可以根据差异轻松限制它。

查询匹配文档在修改之前的所有值。这确保了自用户打开它以来它没有被更改。

db.people.findAndModify( {
   query: {
        name:'bruce',
        surname:'wayne',
        job:'batman',
        email:'onlyifdanger@batman.com',
    },    
   update: {
        name:'bruce',
        surname:'wayne',
        job:'business owner',
        email:'bruce@wayne.com',
    },
   upsert: true
   // uncomment next line to get the updated / new document return
   // ,new : true
} );
于 2013-03-18T16:58:09.950 回答
1

听起来您正在寻找更新结果的特定字段而不是整个对象本身。即如果用户提供名称的更新参数,您只想更新数据库中的名称。使用您的名字:'bruce albert' 示例,newUserInfo 将是

newUserInfo: {
  name: 'bruce albert',
  surname: '',
  job: '',
  email: ''
}

并且您不想简单地使用这些值进行更新,因为您要么擦除已有的信息,要么添加一条信息较少的重复记录。

在这种情况下,您只能优化到目前为止。

  1. 如果用户存在,则查询数据库
  2. 如果存在,则获取数据库的值
  3. 将数据库的值与用户发送的表单值进行比较
  4. 如果数据库中的值相等,则丢弃该操作
  5. 如果数据库中的值不同,则使用表单值更新值
  6. 关闭数据库并发送响应

步骤 1 和 2 可以合并,因为 findOne() (或类似的东西)将返回记录匹配参数,但前提是对象存在。如果它不存在,您可能需要插入用户传递的值。

可以删除第 4 步,因为本质上它什么也没做。

第 5 步可能是最重要的,因为您必须定义值如何“不同”。想一想,你想用 job='' 更新吗?因为这与“蝙蝠侠”“不同”,尽管您可能不想使用该值进行更新。

我的步骤是

  1. 查看该记录是否存在于数据库中。
    • 如果不是,请插入对象并转到步骤 3
    • 如果是,请转到步骤 2
  2. 将数据库对象中的值与用户提供的值进行比较。
    • 如果值不同(以您想要的方式),请根据需要更新每个字段。
    • 如果值相同,则无事可做,转到步骤 3
  3. 关闭数据库并向用户发送响应

希望这可以帮助。

于 2013-03-18T12:43:15.453 回答