我使用NodeJS,ExpressJS和Mongoose Mongo ORM。
我的架构如下。
const chatMessageSchema = new Schema({
_id: {
type: String,
default: () => (uuidV1().replace(/-/g, ''))
},
roomid: String,
message: Schema.Types.Mixed,
type: String, // text, card, qrt, attachment
notes: [notesSchema],
posted_by_user: String,
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
},
collection: 'ChatMessages'
});
注释的嵌套子模式如下;
const notesSchema = new Schema({
_id: {
type: String,
default: () => (uuidV1().replace(/-/g, ''))
},
roomid: String,
messageid: String,
message: Schema.Types.Mixed,
type: String, // text, attachment
posted_by_user: String,
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}});
最初,当用户创建chatMessage时,注释默认最初保存为空数组[]。
用户可以在创建消息后显式创建注释消息,注释是数组子文档。
现在发生的事情就是当我得到一个消息列表时。我需要显示posted_by_user这是一个字符串的id。对于该字符串的id,我执行$lookup
获取用户配置文件。聚合如下。
return this.aggregate([
{ $match : {roomid: roomid} },
{ $sort: {created_at: -1} },
{
$lookup: {
from: "RefUserProfiles",
localField: "posted_by_user",
foreignField: "_id",
as: "posted_by_user"
}
},
{ $unwind: "$posted_by_user" },
{ $skip: pageOptions.page * pageOptions.limit },
{ $limit: pageOptions.limit },
{ $sort: {created_at: 1} },
{
$unwind: { path: "$notes", preserveNullAndEmptyArrays: true }
},
{
$lookup: {
from: "RefUserProfiles",
localField: "notes.posted_by_user",
foreignField: "_id",
as: "notes.posted_by_user"
}
},
{
$unwind: { path: "$notes.posted_by_user", preserveNullAndEmptyArrays: true }
},
{
$group: {
_id: "$_id",
created_at: { $last: "$created_at" },
roomid: { $last: "$roomid" },
message: { $last: "$message" },
notes: { $addToSet: "$notes" },
type: { $last: "$type" },
posted_by_user: { $last: "$posted_by_user" },
read_by_recipients: { $last: "$read_by_recipients" },
}
}
]);
现在,因为在某些情况下,某些消息的注释是一个空数组,因此对于非常特殊的情况,我在响应中得到的对象就像[{}]
。是这样的假设。或者是否有更好的用例。
例如,我根据此查询获得的响应如下。
"conversation": [
{
"_id": "7cdbf630e6ec11e79166559abfb987ac",
"created_at": "2017-12-22T07:48:23.956Z",
"roomid": "aacc6b70e68211e79166559abfb987ac",
"message": {
"text": "message 1"
},
"notes": [{}],
"type": "text",
"posted_by_user": {
"id": "4d6fd5a95d57436d944586a1d5b2b2ff",
"name": "Adeel Imran",
"profilePicture": "",
"phone": "",
"email": "",
"designation": "",
"type": "user"
},
},
{
"_id": "80d91470e6ec11e79166559abfb987ac",
"created_at": "2017-12-22T07:48:30.648Z",
"roomid": "aacc6b70e68211e79166559abfb987ac",
"message": {
"text": "message 4"
},
"notes": [
{
"posted_by_user": {
"id": "86049b3d28f640a8a6722c57b73a292e",
"name": "Paul Johnson",
"profilePicture": "",
"phone": "",
"email": "",
"designation": "",
"type": "sp"
},
"type": "text",
"message": {
"text": "yeah "
},
"messageid": "26401d30e5a511e7acc4c734d11adb25",
"roomid": "27d3ed80e0cc11e78318b3cd036890f2",
"updated_at": "2017-12-20T16:45:44.132Z",
"created_at": "2017-12-20T16:45:44.132Z",
"_id": "38ad3750e5a511e7acc4c734d11adb25"
}
],
"type": "text",
"posted_by_user": {
"id": "4d6fd5a95d57436d944586a1d5b2b2ff",
"name": "Adeel Imran",
"profilePicture":"",
"phone": "",
"email": "",
"designation": "",
"type": "user"
},
}
],
对此有任何建议或指示将受到高度赞赏。感谢您抽出宝贵时间来回顾这个问题。
干杯。