6

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

我知道 upserts,但我不确定它们是否是最好的解决方法?当谈到如何实际编写与“$push”语句一起使用的 upsert 时,我有点困惑。

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

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

..在哪里:

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

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

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

4

3 回答 3

11

为我的问题找到了更好的答案:

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

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

如果我刚刚使用了 $push,它总是会在用户集合中的“活动”中创建重复的元素。这发生在有和没有 upsert 的情况下。

出于某种原因,$each 不起作用但不是必需的,我猜 PyMongo 会为我解决这个问题。

于 2012-06-18T10:14:17.020 回答
9

根据MongoDB DocsPyMongo Docs通过更新的第三个参数作为 true 发送。

self.users.update({"user_id": event['userid']}, {'$push': {'campaigns': UserCampaign}}, True)
于 2012-06-13T14:25:03.660 回答
1

克里斯蒂安在他的回答中有正确的论据,所以我将不理会那部分(赞成他的回答)。

但是,您还询问避免重复等。

这里的关键是确保更新查询的条件部分特定于您想要的级别。upsert(或更新)仅与您传递给它的标准一样好。如果 upsert 没有找到与条件匹配的文档,则 upsert 将插入一个新文档,并且 update 将仅在找到传入的条件时执行 $push (或指定的任何更新)(如果不止一个,您可以进行多重更新doc也被发现)。

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

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

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

于 2012-06-13T14:46:02.837 回答