使用 upsert 和多语法更新 Mongodb

Posted

技术标签:

【中文标题】使用 upsert 和多语法更新 Mongodb【英文标题】:Mongodb update with upsert and multi syntax 【发布时间】:2013-04-25 17:18:20 【问题描述】:

我是 mongodb 的新手,由于 mongodb 的文档不完整,让我不得不反复试验……遗憾的是,我所有的尝试都没有成功,这让我对正在发生的事情以及要调试的内容感到困惑。 ..

我只需要更新数据库中匹配某些条件的多条记录,对于不存在的记录,为此创建新条目。我相信我可以通过 update、upsert 和 multi 的单一数据库访问来做到这一点。这是我想出的:

dbschema.Person.update(  person_id:  $in: ["734533604" ,"701084015"]  ,  $set: "scores": 1200 ,  options:  upsert: true, multi: true   );

我也尝试过多种组合,甚至是旧版本,例如:

dbschema.Person.update(  person_id:  $in: ["734533604" ,"701084015"]  ,  $set: "scores": 1200 ,  upsert: true ,  multi: true  );

它们都不起作用...

请帮我解决这些琐碎的事情...我可以在 sql 中轻松完成,但是 nosql 对我来说太有限了...谢谢!

编辑:

find 上的相同查询完美运行:

dbschema.Person.find(  person_id:  $in: ["734533604" ,"701084015"]  , function ( err, results ) 
    console.log( 'result: ' + results );
    console.log( 'error: ' + err );
    console.log( 'result length: ' + results.length );
 );

编辑:

我希望创建“未找到”记录,并更新找到的记录。我的逻辑可能有缺陷,我现在很困惑。

本来,我是一次find()-ing一条记录,改变值,并为每条修改的记录调用save(),但是当我部署到live时,响应时间变得慢了数百倍,尤其是当每个请求需要更新数百条记录时。

然后我发现find() + $in,性能恢复了,甚至比以前(查询时)更好,但是更新仍然慢得不能接受。所以,现在我正在寻找更新所有文档的方法一个查询..

我通常在 SQL 中做的是使用 UPDATE WHEN CASE THEN... 例如:

UPDATE person SET score = CASE
WHEN person_id = "734533604" THEN 1200
WHEN person_id = "701084015" THEN 1200
ELSE
score
END

【问题讨论】:

无法将 upsert 与 $in 一起使用,因为 upsert 可以一次插入一个 personid,并且会混淆第一个值和第二个值 你有几个问题,一些是语法上的,而另一些是设计上的。如果您正在寻找 2 条匹配的记录但没有找到,您是否希望同时创建这两条记录?如果找到两个之一,您是否希望更新一个并创建一个? Upsert 最多可以创建一个新记录,这就是为什么 multi 和 upsert 有时不能一起使用。 是的,如果找不到,我希望两者都被创建,如果找到,则更新,而那些未找到的则被创建..你是对的,我很困惑也许我的逻辑也有缺陷..但我会解释为什么我要这样做.. 【参考方案1】:

您不能根据不同的标准更新多条记录,并期望“upsert”能够理解您的意思。 Upsert 标志最多可以插入一个文档,如果您检查文档,您会发现在 upsert 的情况下使用“复合”更新标准是没有意义的。

在您的示例中,插入应该使用两个 fbid 值中的哪一个?

我认为在您的情况下,您可以采取多种方法(都涉及不止一个操作)。您可以在循环调用 update 中使用 upsert 标志更新每个 fbid 值 - 这将像您期望的那样工作,如果未找到 fbid 将创建一个新文档。其他方式涉及在运行更新之前进行查询,但我认为这些方式可能更容易出现竞争条件。

以下是对更新工作原理的说明 - 我觉得它非常完整: http://docs.mongodb.org/manual/core/update/#update-operations-with-the-upsert-flag

【讨论】:

谢谢,我期待更新或插入 $in 中的所有记录。我不确定这是否是这样做的方法,因为我正在尝试优化许多正在扼杀我的响应时间的插入/更新。您知道如何插入/更新大量记录并最好一次性保存吗? 如果我理解你的问题,没有办法做到这一点。 链接已消失 404。 谢谢。现在已经修复了。

以上是关于使用 upsert 和多语法更新 Mongodb的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 clojure.java.jdbc 进行 UPSERT

mongoDB 更新数据

使用 upsert 更新:true 是否在 express 中更新,猫鼬?

mongo数据更新

SQLCE - Upsert(更新或插入) - 如何使用常用方法准备一行?

如何确定 upsert 是不是是 PostgreSQL 9.5+ UPSERT 的更新?