如何在MongoDB中更新重复的文档?

3
我遇到了更新重复字段的问题。需要执行以下操作:
查找具有相同ipAddr、相同bccId且active为True的文档。
如果它们的sessionId字段不同,则需要将最后更新时间较早的项的active字段更新为false。
目前,我正在尝试获取所有重复项。我找到了几个链接来解决这个问题,但是到目前为止都没有起作用。
这是我需要更新的一个项目的情况描述:
db.mycollection.insert(
   [
        {
            "_id" : 12345,
            "bccId" : "1",
            "ipAddr" : "1",
            "sessionId" : "1",
            "updateTime" : ISODate("2010-02-11T01:05:35Z"),
            "active" : true,

        },

        {
            "_id" : 12346,
            "bccId" : "1",
            "ipAddr" : "1",
            "sessionId" : "2",
            "updateTime" : ISODate("2016-02-11T01:05:35Z"),
            "active" : true,

        },
   ]
)

他们的bccId、ipAddr和active都相同,但sessionIds不同。

所以在找到这两个之后,我需要比较它们的updateTime。最近更新的应该保持活跃状态,其他所有的应该被更新,所以现在的活动状态应该为false。

硬编码这些值,我可以像这样找到重复项的列表:

db.mycollection.aggregate([{ $match: { ipAddr: "1", bccId: "1", active: true } }])

但我无法想出如何让它与系统中的其他文档进行比较,而不是使用硬编码值。当我尝试使用分组时,它没有起作用,因为可能存在大量重复项,我需要按相同的ipAddr和bccId分组获取它们。此外,我不确定这是否是获取列表然后将日期进行比较以更新字段的正确方法。

在弄清楚之后,我将需要将其解析为Java,因此不确定是否应直接转到Java开发来创建查询。如果有人能帮我找出解决此问题的最佳方法,将不胜感激。

谢谢!


为什么你的_id是一样的? - Krishna
抱歉,只是打错了字。将“_id”更改为不同的值了。 - Igor
您可以稍微更改架构,通过在 {ipAddr: 1, bccId: 1} 上放置唯一索引来帮助您仅跟踪活动会话,以便始终只有一个条目存在。为了跟踪旧会话,您可以将它们保存在辅助集合中的其他位置。 - hyades
不行啊...客户不想对结构做任何更改,所以我们不能在那里做任何修改 :P - Igor
1个回答

0

所以这是我做的:

db.mycollection.aggregate([
    {
        "$match": 
        { 
            "active": true 
        }
    },
    {
        "$sort":
        {
            "updateTime": -1

        }
    },
    {
        "$group": 
        {
            "_id": 
            {
                "ipAddr": "$ipAddr", 
                "bccId": "$bccId"
            },
            "session": 
            {
                "$push": {
                    "sessionId": "$sessionId",
                    "updateTime": "$updateTime"
                }
            },
            "sessionCount":
            {
                "$sum": 1
            }
        }
    }
])

使用聚合操作将返回一个游标。然后我只需遍历该游标并在其中执行所需的更新,其中bccId和ipAddr相同,并且不等于列表顶部的会话ID(因为我已经按照updateTime排序,第一个将是最近的,我想保持活动状态)。
就这样 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接