我们在mongodb中存储了以下文档集:
对话记录:
{_id: "x", lang: "en", timestamp: "", ... }
每个会话都有许多进程,每个进程都有一组消息作为子文档列表。 处理记录:
{_id: "y", conversationId: "x", name: "", timestamp: "", messages: [
{
"direction" : "out",
"text" : "How can I help you?",
"timestamp" : ISODate("2019-05-23T11:08:18.423Z"),
"_id" : 3
},
{
"direction" : "out",
"text" : "Hello",
"timestamp" : ISODate("2019-05-23T11:08:17.423Z"),
"_id" : 1
},
{
"direction" : "in",
"text" : "Hi",
"timestamp" : ISODate("2019-05-23T11:08:18.423Z"),
"_id" : 2
}
], completed: "true"}
我需要进行aggregate
查询,并获取对话列表,而每个对话都应具有按时间戳排序的进程列表,并且每个进程应仅具有 last 消息( (从“入”和“出”两个方向的“ strong>基于ID字段)。
我们需要得到这样的东西:
[
{
conversationId: "x",
timestamp: "",
processes: [
{
_id: "y",
name: "",
timestamp: "",
lastInMessage: {
"direction": "in",
"text": "Hi",
"timestamp": ISODate("2019-05-23T11:08:18.423Z"),
"_id": 2
},
lastOutMessage: {
"direction": "out",
"text": "How can I help you?",
"timestamp": ISODate("2019-05-23T11:08:18.423Z"),
"_id": 3
}
},
{
_id: "y",
name: "",
....
}
]
}
]
我尝试过的查询是:
conversation.aggregate([
{
$match: {
timestamp: query.timestamp
}
},
{
$project: {
_id: "$conversationId",
timestamp: "$timestamp",
conversationId: "$conversationId"
}
},
{
"$lookup":
{
"from": "processes",
"localField": "conversationId",
"foreignField": "conversationId",
"as": "process"
}
},
{
$project: {
_id: "$_id",
timestamp: "$timestamp",
// messages: "$process.messages",
processes: "$process"
}
},
// here I don't know what to do.
答案 0 :(得分:1)
您可以使用$reduce来计算数组的最小值和最大值,并可以使用$map来生成所有process
值的集合:
{
$project: {
_id: "$_id",
timestamp: "$timestamp",
processes: {
$map: {
input: "$processes",
as: "process",
in: {
_id: "$$process._id",
name: "$$process.name",
timestamp: "$$process.timestamp",
lastInMessage: {
$reduce: {
input: "$$process.messages",
initialValue: null,
in: {
$cond: [
{ $and: [ { $eq: [ "$$this.direction", "in" ] }, { $gt: [ "$$this.timestamp", "$$value.timestamp" ] } ] },
"$$this",
"$$value"
]
}
}
},
lastOutMessage: {
$reduce: {
input: "$$process.messages",
initialValue: null,
in: {
$cond: [
{ $and: [ { $eq: [ "$$this.direction", "out" ] }, { $gt: [ "$$this.timestamp", "$$value.timestamp" ] } ] },
"$$this",
"$$value"
]
}
}
}
}
}
}
}
}