如果元素不存在,则将元素推送到数组(无重复)

时间:2012-06-13 14:13:53

标签: python mongodb

我有一个事件集合,我正在查找特定事件的类别,然后我使用$ push语句更新我的其他集合。问题是,当两个事件具有相同的类别时,它将创建一个我不想要的副本。

我知道upserts但我不确定他们是否是最好的方法呢?当涉及到如何实际编写一个与“$ push”-statement一起使用的upsert时,我有点困惑。

这就是我的更新现在的样子:

self.users.update({"user_id": event['userid']}, {'$push': {'campaigns': UserCampaign}})

...其中:

UserCampaign = {
        "id": campaign['id'],
        "name": campaign['name']
}

“UserCampaign”不时会收到相同的信息,因为我的收藏可能非常庞大,我希望尽可能高效地完成这项工作。

TLDR;我希望使用“推送”更新找到的文档中的数组,而不会有重复的风险。

3 个答案:

答案 0 :(得分:11)

找到了解决问题的更好方法:

通过使用$ addToSet,它没有创建重复项(我还确保通过将所有词典添加到列表中来确保之前没有重复):

self.users.update({"user_id": event['userid']}, {'$addToSet': {'campaigns': UserCampaigns[i]}})

如果我刚使用了$ push,它总是会在'广告系列中创建重复的元素。在用户集合中。无论是否有upsert都会发生这种情况。

出于某种原因,每个人都没有工作但是没有必要,我猜PyMongo会为我照顾。

答案 1 :(得分:9)

根据MongoDB DocsPyMongo Docs,将您的更新的第三个参数发送为true。

self.users.update({"user_id": event['userid']}, {'$push': {'campaigns': UserCampaign}}, True)

答案 2 :(得分:1)

克里斯蒂安在答案中有正确的论据,所以我将单独留下这一部分(赞成他的回答)。

但是,你也要求避免重复等。

此处的关键是确保更新查询的条件部分特定于您想要的级别。 upsert(或更新)仅与您传入其中的条件一样好。如果找不到符合条件的文件,则upsert将插入新文档,如果找到传入的条件,则update将仅执行$ push(或指定的任何更新)(如果多于一个,则可以进行多次更新) doc也被发现了)。

在您的情况下,标准部分是:

UserCampaign = {
        "id": campaign['id'],
        "name": campaign['name']
}

确保这部分是唯一的,你会没事的 - 如果这可以匹配多个文件,那么你将会有重复。