0

我收集messages了以下文件

{
  "_id" : ObjectId("5164218f359f109fd4000012"),
  "receiver_id" : ObjectId("5164211e359f109fd4000004"),
  "sender_id" : ObjectId("5162de8a359f10cbf700000c"),
  "body" : "Hello Billy!!!",
  "readed" : false,
  "updated_at" : ISODate("2013-04-09T14:11:27.17Z"),
  "created_at" : ISODate("2013-04-09T14:11:27.17Z")
}

我需要查询给定用户(按reciever_id+sender_id 字段分组)并按created_at 排序的接收最后一条消息(不管是接收还是发送)。

为了更好地解释这个问题,我在 SQL 中是如何做到的一个例子:

SELECT DISTINCT ON (sender_id+receiver_id) * FROM messages 
    ORDER by (sender_id+receiver_id), created_at DESC
    WHERE sender_id = given_user or receiver_id = given_user 

我不明白如何用mondodb解决这个问题。

4

2 回答 2

2

MongoDB 2.2+ 中的聚合框架为您的查询提供了最明显的翻译。MongoDB 手册包含一个SQL 到聚合框架映射图表作为一般指南,尽管这两种方法存在明显差异。

这是一个注释示例,您可以在mongoshell 中尝试:

var given_user = ObjectId("5162de8a359f10cbf700000c");
db.messages.aggregate(
    // match: WHERE sender_id = given_user or receiver_id = given_user
    // NB: do the match first, because it can take advantage of an available index
    { $match: {
        $or:[
            { sender_id: given_user },
            { receiver_id: given_user },
        ]
    }},

    { $group: {
        //  DISTINCT ON (sender_id+receiver_id)
        _id: { sender_id: "$sender_id", receiver_id: "$receiver_id" }
    }},

    // ORDER by (sender_id+receiver_id), created_at DESC
    { $sort: {
        sender_id: 1,
        receiver_id: 1,
        created_at: -1
    }}
)

样本结果:

{
    "result" : [
        {
            "_id" : {
                "sender_id" : ObjectId("5162de8a359f10cbf700000c"),
                "receiver_id" : ObjectId("5164211e359f109fd4000004")
            }
        }
    ],
    "ok" : 1
}

您可能希望在分组上添加其他字段,例如收到的消息计数。

如果你真的想将 sender_id+receiver_id 组合成一个字段,你可以使用$concatMongoDB 2.4+ 中的操作符。

于 2013-04-09T15:41:53.233 回答
1

没有明确的方法可以这样做。让我们回顾一下解决方法:

方式1:在代码级别(在find之后)执行distinct,然后只需使用find

db.message.find({$or:[{sender_id:?}, {receiver_id:?}]})

方式2:使用聚合框架:

db.message.aggregate( [
   {$match: {$or:[{sender_id:?}, {receiver_id:?}]},
    $group: { _id: {sender:"$sender_id", receiver:"$receiver_id"},
               other: { ... } } },
   $sort: {sender_id,receiver_id,...}
   ] ) 

这种方式问题出现在排序级别,因为sender_id, receiver_idsender_id+receiver_id

方式 3:引入代理字段 sender_id+receiver_id 然后使用find或什distinct至根据 Stennie 提示。

于 2013-04-09T15:28:20.603 回答