我试图弄清楚如何在MongoDB中更新集合。基本上,我想列出一个电子邮件地址,检查它们是否存在于数据库中,如果不存在,则从它们中创建一个新用户,所有这些都在同一查询中。这可能吗?
现在我正在这样做:
const usersWithEmailsOnly = [<array-of-emails];
User.update({
email: {
$in: usersWithEmailsOnly.map(userWithEmail => userWithEmail.email),
},
}, { multi: true, upsert: true }).exec()
然后我从服务器获得以下响应:
{ ok: 0, n: 0, nModified: 0 }
当我查看数据库时,看到没有创建用户。还有什么我需要做的吗?
答案 0 :(得分:2)
Users.bulkWrite(
usersWithEmailsOnly.map(userWithEmail =>
({
"updateOne": {
"filter": { "email": userWithEmail.email },
"update": { "$setOnInsert": { "name": userWithEmail.name } },
"upsert": true
}
})
)
)
这与$setOnInsert
更新运算符结合使用,后者具有特殊条件:只有实际的“ upsert / insert” 发生时,指定的参数才 更新文档。因此,当匹配的现有文档是唯一使用的运算符时,它根本不会接受任何更改。
请注意,“ upserts” 将始终应用update语句的 query / predicate 部分中使用的条件,只要该表达式等于单数即可;即age: { $gt: 3 }
不会是单数。对于大多数“数据加载” ,您通常希望创建一个静态谓词作为“唯一键” ,因此需要选择更新以及 some 其他数据,您可以根据需要在其中应用$setOnInsert
。
从技术上讲,它仍然是多个更新,但是与尝试循环代码中的一系列更新不同,这是与服务器之间的单个请求和响应。从应用程序的角度来看,它几乎具有与单个写入相同的响应速度(当然还有有效负载开销)。
没有真正的“单个语句” 这样的东西,因为不同的数据更新标准无法应用于MongoDB更新中的多个文档。您可以应用相同数据来更新多个文档,但是当您希望“此条件与文档匹配时,则意味着我会在发生这种情况时使用此特定数据进行更新” ,那就是您使用bulkWrite()
的目的。