您能在 Mongo 中为 $addToSet 指定一个密钥吗?

我有一份文件:

{ 'profile_set' :
[
{ 'name' : 'nick', 'options' : 0 },
{ 'name' : 'joe',  'options' : 2 },
{ 'name' : 'burt', 'options' : 1 }
]
}

并且如果名称不存在(不管选项如何) ,则希望向 profile_set集添加一个新文档。

所以在这个例子中,如果我试图加上:

{'name' : 'matt', 'options' : 0}

它应该添加它,但添加

{'name' : 'nick', 'options' : 2}

应该什么也不做,因为即使 option不同,名称为 nick的文档也已经存在。

Mongo 似乎与整个元素相匹配,我最后检查它们是否相同,最后得到

profile_set containing [{'name' : 'nick', 'options' : 0}, {'name' : 'nick', 'options' : 2}]

有没有办法用 $addToSet做到这一点,还是我必须按下另一个命令?

29266 次浏览

You can qualify your update with a query object that prevents the update if the name is already present in profile_set. In the shell:

db.coll.update(
{_id: id, 'profile_set.name': {$ne: 'nick'}},
{$push: {profile_set: {'name': 'nick', 'options': 2}}})

So this will only perform the $push for a doc with a matching _id and where there isn't a profile_set element where name is 'nick'.

As of MongoDB 4.2 there is a way to do this using aggregation expressions in update.

For your example case, you would do this:

newSubDocs = [ {'name' : 'matt', 'options' : 0}, {'name' : 'nick', 'options' : 2} ];
db.coll.update( { _id:1 },
[
{$set:  { profile_set:  {$concatArrays: [
"$profile_set",
{$filter: {
input:newSubDocs,
cond: {$not: {$in: [ "$$this.name", "$profile_set.name" ]}}
}}
]}}}
])