我有一个 "聊天 "的猫鼬 Schema
它具有以下属性。
const schema = mongoose.Schema({
...
recipient: {
type: mongoose.Types.ObjectId,
required: true,
ref: 'User',
},
sender: {
type: mongoose.Types.ObjectId,
required: true,
ref: 'User',
},
content: {
type: String,
},
...
}, {
timestamps: true,
});
一般来说,我想获取一个用户拥有的每条覆盖信息的最后一条信息。意味着我需要提供一个用户id(可以存储在 sender
或 recipient
字段),并取回最后一条消息(用 createdAt
)的用户与其他每个用户的关系。
例子:假设我有以下内容 document
s:
[
{
recipient: "One",
sender: "Two",
createdAt: ISODate("2014-01-01T08:00:00Z"),
},
{
recipient: "One",
sender: "Three",
createdAt: ISODate("2014-02-15T08:00:00Z")
},
{
recipient: "Two",
sender: "One",
createdAt: ISODate("2014-02-16T12:05:10Z")
}
]
把 "一 "作为输入 -- 从 "一 "中得到的理想结果 Model.find(...)
是的,我有一个mongoose.Schema,它有以下属性: const schema = mongoose.Schema({ ..:
[
{
recipient: "One",
sender: "Three",
createdAt: ISODate("2014-02-15T08:00:00Z")
},
{
recipient: "Two",
sender: "One",
createdAt: ISODate("2014-02-16T12:05:10Z")
}
]
使用示例数据。
[
{
recipient: "One",
sender: "Two",
createdAt: ISODate("2014-01-01T08:00:00Z"),
content: "Hi Mr. One! - Two"
},
{
recipient: "One",
sender: "Three",
createdAt: ISODate("2014-02-15T08:00:00Z"),
content: "Hello One! - Three"
},
{
recipient: "Two",
sender: "One",
createdAt: ISODate("2014-02-16T12:05:10Z"),
content: "Whats up, Two? - One"
}
]
看一下下面的聚合: https:/mongoplayground.netpDTSDWX3aLWe
它...
One
)conversationWith
领域使用 $addFields 其中包含 recipient
如果是信息 向用户一 或 sender
如果是信息 由用户One发送conversationWith
字段,并将最近的信息返回为 firstMessage
完整的聚合流水线。
db.collection.aggregate([
{
$match: {
$and: [
{
$or: [
{
recipient: "One"
},
{
sender: "One"
}
],
},
]
}
},
{
$addFields: {
conversationWith: {
$cond: {
if: {
$eq: [
"$sender",
"One"
]
},
then: "$recipient",
else: "$sender"
}
}
}
},
{
$sort: {
createdAt: -1
}
},
{
$group: {
_id: "$conversationWith",
firstMessage: {
$first: "$$ROOT"
}
}
}
])
利用mongoplayground你可以逐一删除聚合步骤 看看每个步骤的作用。
试试。
以获得最佳理解。
你可以通过下面的查询汇总来实现这个目的。
工作实例-- https:/mongoplayground.netpwEi4Y6IZJ2v。
db.collection.aggregate([
{
$sort: {
recipient: 1,
createdAt: 1
}
},
{
$group: {
_id: "$recipient",
createdAt: {
$last: "$createdAt"
}
}
},
{
$project: {
_id: 0,
recipient: "$_id",
createdAt: "$createdAt"
}
}
])
如果你有两个字段要匹配,那么你可以使用下面的查询方式。
工作实例 - https:/mongoplayground.netpRk5MxuphLOT。
db.collection.aggregate([
{
$match: {
$or: [
{
sender: "One"
},
{
recipient: "One"
}
]
}
},
{
$addFields: {
other: {
$cond: {
if: {
$eq: [
"$recipient",
"One"
]
},
then: "$sender",
else: "$recipient"
}
}
}
},
{
$sort: {
createdAt: 1
}
},
{
$group: {
_id: "$other",
createdAt: {
$last: "$createdAt"
},
recipient: {
$last: "$recipient"
},
sender: {
$last: "$sender"
}
}
},
{
$project: {
_id: 0,
recipient: "$recipient",
sender: "$sender",
createdAt: "$createdAt"
}
}
])