MongoDB聚合并匹配返回的键

事情是,我正在写一些代码从我的数据库获取用户消息。 数据库有sent_tosent_by消息键和命令我下面得到的数据键是

db.users_messages.aggregate({$group: {_id: {to: "$sent_to", by: "$sent_by"}}}) 

这将返回所有sent_tosent_by Users_IDs的列表。 现在让我们假设,如果user1已经发送消息给user2 ,同时user2已经回复给user1 ,我希望它只返回user1 user2 ,而不是user2 user1 。 而当我稍后检查这个东西的时候,我还剩下分页的事情,因为我正在对汇总应用$限制 。 希望有人能帮助!

你所要求的是一个不小的壮举,我认为这里真正的解决scheme是在你的文档中包含更多的元数据,特别是以一致的方式表示谁是对话的“中间”。

我的意思是,无论是谁发送信息或接收信息,“对话”都需要独特的对话。 考虑这两个基本文件。

 { "from": 1, "to": 2, "between": [1,2] }, { "from": 2, "to": 1, "between": [1,2] } 

在每种情况下,“从”和“到”是每个“用户”的唯一标识符,其总是以特定方式sorting。 “之间”的数据总是按照相同的顺序sorting,这可以在创build代码时完成,也可以通过$sort修饰符和$each “upsert”function来完成,但是要保持这个“唯一”键用于确定哪些文档属于同一个分组。

单独使用聚合框架也是可以的,但是当你考虑到你可以在你的文档中保留这个框架时,它实际上是不必要的。

 db.converse.aggregate([ { "$group": { "_id": "$_id", "from": { "$push": "$from" }, "to": { "$push": "$to" } }}, { "$project": { "between": { "$setUnion": [ "$from", "$to" ] } }}, { "$unwind": "$between" }, { "$sort": { "between": 1 } }, { "$group": { "_id": "$_id", "between": { "$push": "$between" } }}, { "$group": { "_id": "$between", "count": { "$sum": 1 } }} ]) 

在MongoDB 2.6以前的版本中,如果没有可用的** $setUnion可以用不同的方式组合成一个数组:

 db.converse.aggregate([ { "$project": { "from": 1, "to": 1, "type": { "$const": [ "from", "to" ] }, }}, { "$unwind": "$type" }, { "$group": { "_id": "$_id", "between": { "$addToSet": { "$cond": [ { "$eq": [ "$type", "from" ] }, "$from", "$to" ] } } }}, { "$unwind": "$between" }, { "$sort": { "between": 1 } }, { "$group": { "_id": "$_id", "between": { "$push": "$between" } }}, { "$group": { "_id": "$between", "count": { "$sum": 1 } }} ]) 

在每一种情况下,都会有一个合理的偏执狂,因为“套装没有订购”。 他们可能碰巧以这种方式出现,但你可能不能指望这一点。

这里的原则基本相同,在“之间”元素中创build一个唯一sorting的“列表”,然后将其用作分组键。 从上面的示例文档中,忽略现有的字段之间的过程将只返回一个计数为“2”的文档,如下所示:

 { "_id" : [ 1, 2 ], "count" : 2 } 

因此,在创build或修改文档时,维护此类数据是非常有意义的。 这样分组变得简单,因为“唯一密钥”已经被识别