在我的mongodb数据库中,我有一个消息集合,用于在用户之间发送私人消息。我想检索用户的对话。我有这个数据模型:
更新的 json
{
"_id" : ObjectId("577f81fde4501ba208b0e470"),
"text" : "This is a message",
"sender_profile_id" : ObjectId("577e69b0794f49d962f10e85"),
"receiver_profile_id" : ObjectId("577e57393db745060b532000"),
},
{
"_id" : ObjectId("577f81fde4501ba208b0e470"),
"text" : "This is a message",
"sender_profile_id" : ObjectId("577e57393db745060b532000"),
"receiver_profile_id" : ObjectId("577e69b0794f49d962f10e85"),
},
{
"_id" : ObjectId("577f81fde4501ba208b0e470"),
"text" : "This is a message",
"sender_profile_id" : ObjectId("577e57393db745060b532000"),
"receiver_profile_id" : ObjectId("577e69b0794f49d962f10e82"),
},
{
"_id" : ObjectId("577f81fde4501ba208b0e470"),
"text" : "This is a message",
"sender_profile_id" : ObjectId("577e69b0794f49d962f10e82"),
"receiver_profile_id" : ObjectId("577e57393db745060b532000"),
},
理论上有了这个 json,我有 2 个用户 ObjectId 的对话("577e57393db745060b532000")。如何检索它们?
更新的解决方案
我解决了这个问题:
var selector = {};
selector['$or'] = [
{"sender_profile_id" : ObjectId(decoded.profile._id)},
{"receiver_profile_id" : ObjectId(decoded.profile._id)}
];
selector['_acl'] = {$exists : true};
selector['_acl.' + decoded.profile._id] = {$exists : true};
selector['_acl.' + decoded.profile._id + '.read'] = true;
var query = {
$match : selector
};
var group = {
$group: {
_id: "$_id",
text : { $last: '$text' },
sender_profile_id : { $last: '$sender_profile_id' },
receiver_profile_id : { $last: '$receiver_profile_id' },
receiver : {$addToSet : '$receiver_profile_id'},
sender: {$addToSet : '$sender_profile_id'},
created_at : { $last: '$created_at' },
updated_at : { $last: '$updated_at' },
count: { $sum: 1 }
}
};
var project = {
$project: {
_id: "$_id",
text: "$text",
sender_profile_id: '$sender_profile_id',
receiver_profile_id: '$receiver_profile_id',
created_at : '$created_at',
updated_at : '$updated_at',
participants : {
$cond: {
if: {
$gte: ["$sender", "$receiver"] },
then: { "$setUnion": ["$receiver", "$sender"] },
else: { "$setUnion": ["$sender", "$receiver"] }
}
}
}
};
var group2 = {
$group: {
_id: "$participants",
text : { $first: '$text' },
sender_profile_id : { $first: '$sender_profile_id' },
receiver_profile_id : { $first: '$receiver_profile_id' },
created_at : { $first: '$created_at' },
updated_at : { $first: '$updated_at' },
count: { $sum: 1 }
}
};
var project2 = {
$project: {
_id : 0,
participants : "$_id",
text: "$text",
interlocutor_profile_id: {
$cond: {
if: {"$eq": [ "$receiver_profile_id", ObjectId(decoded.profile._id)]},
then: '$sender_profile_id',
else: '$receiver_profile_id'
}
},
created_at : 1,
updated_at : 1,
count: 1
}
}
var sort = {
$sort: {
"created_at": -1
}
}
var sort2 = {
$sort: {
"created_at": -1
}
}
db.collection('message').aggregate(query, group, project, sort, group2, project2, sort2, function(error, result)
试试这个:
db.aggregate([ {$match: {$or: [{'sender._id': 'ObjectId("577e57393db745060b532000")','receiver._id': 'ObjectId("577e69b0794f49d962f10e85")'},{'sender._id': 'ObjectId("577e69b0794f49d962f10e85")','receiver._id': 'ObjectId("577e57393db745060b532000")'}]}}, {$group: { _id: '$sender._id', vals: { '$push': '$receiver._id' } }} ])
为我的问题找到了解决方案:
var selector = {};
selector['$or'] = [
{"sender_profile_id" : ObjectId(decoded.profile._id)},
{"receiver_profile_id" : ObjectId(decoded.profile._id)}
];
selector['_acl'] = {$exists : true};
selector['_acl.' + decoded.profile._id] = {$exists : true};
selector['_acl.' + decoded.profile._id + '.read'] = true;
var query = {
$match : selector
};
var group = {
$group: {
_id: "$_id",
text : { $last: '$text' },
sender_profile_id : { $last: '$sender_profile_id' },
receiver_profile_id : { $last: '$receiver_profile_id' },
receiver : {$addToSet : '$receiver_profile_id'},
sender: {$addToSet : '$sender_profile_id'},
created_at : { $last: '$created_at' },
updated_at : { $last: '$updated_at' },
count: { $sum: 1 }
}
};
var project = {
$project: {
_id: "$_id",
text: "$text",
sender_profile_id: '$sender_profile_id',
receiver_profile_id: '$receiver_profile_id',
created_at : '$created_at',
updated_at : '$updated_at',
participants : {
$cond: {
if: {
$gte: ["$sender", "$receiver"] },
then: { "$setUnion": ["$receiver", "$sender"] },
else: { "$setUnion": ["$sender", "$receiver"] }
}
}
}
};
var group2 = {
$group: {
_id: "$participants",
text : { $first: '$text' },
sender_profile_id : { $first: '$sender_profile_id' },
receiver_profile_id : { $first: '$receiver_profile_id' },
created_at : { $first: '$created_at' },
updated_at : { $first: '$updated_at' },
count: { $sum: 1 }
}
};
var project2 = {
$project: {
_id : 0,
participants : "$_id",
text: "$text",
interlocutor_profile_id: {
$cond: {
if: {"$eq": [ "$receiver_profile_id", ObjectId(decoded.profile._id)]},
then: '$sender_profile_id',
else: '$receiver_profile_id'
}
},
created_at : 1,
updated_at : 1,
count: 1
}
}
var sort = {
$sort: {
"created_at": -1
}
}
var sort2 = {
$sort: {
"created_at": -1
}
}
db.collection('message').aggregate(query, group, project, sort, group2, project2, sort2, function(error, result)
您也可以选中$lookup选项。插图见下文http://dbversity.com/joins-in-mongodb-lookup/
尝试以下操作
db.messages.aggregate([{$project: {correspondents: {$cond: { if: {$gte: ["$sender", "$receiver"]}, then: ["$sender", "$receiver"], else: ["$receiver", "$sender"]}}}}, {$group: {_id: "$correspondents", messages: {$addToSet: "$_id"}}}, {$match: {"_id": ObjectId("577e57393db745060b532000")}}])
查询按对话参与者(通讯员)对进行分组,并返回构成对话的消息数组。此外,您可以获取属于特定用户的对话。