所以我的模式在節點和鏈接之間分割。鏈接集合具有類似的檔案
{src: A, dst:B, value:int}
和節點集合有
{name:A, ...other info}
我正在嘗試為節點聚合資訊,以僅使用一種聚合功能來查找已發送與已接收的值資料。
我的聚合函式看起來像
{
"$lookup":{
"from":"links",
"localField":"name",
"foreignField":"dst",
"as":"recv"
}
},
{
"$lookup":{
"from":"links",
"localField":"name",
"foreignField":"src",
"as":"sent"
}
},
然后我只使用 a$project來總結發送/接收陣列的值,導致
{name:A, sent_value:x, recv_value:y}
這沒問題,但我注意到如果我取消其中一個查找,運行時間會顯著減少。我正在尋找一種可能將兩種查找組合到管道的一個階段的方法。我可以很好地分別為 send 和 recv 發出兩個聚合,但我想看看是否可以只使用一個聚合。謝謝
編輯:示例資料
Nodes: {name: "A"}, {name: "B"},{name: "C"}
Links: {src: "A", dst: "B",value:25}, {src: "A", dst: "C", value:3}, {src: "B",dst: "C", value:19}
我想從聚合中得到我上面描述的內容:
{name: "A", sent:28, recv: 0}, {name: "B", sent:19, recv:25}, {name: "C",sent:0,recv:22}
uj5u.com熱心網友回復:
您可以一次$lookup獲取所有 dst 和 src 資料。然后,用于$reduce對陣列執行條件求和。
db.nodes.aggregate([
{
"$lookup": {
"from": "links",
let: {
name: "$name"
},
pipeline: [
{
$match: {
$expr: {
$or: [
{
$eq: [
"$$name",
"$src"
]
},
{
$eq: [
"$$name",
"$dst"
]
}
]
}
}
}
],
"as": "linksLookup"
}
},
{
"$project": {
name: 1,
recv: {
"$reduce": {
"input": "$linksLookup",
"initialValue": 0,
"in": {
"$add": [
"$$value",
{
"$cond": {
"if": {
$eq: [
"$$this.dst",
"$name"
]
},
"then": "$$this.value",
"else": 0
}
}
]
}
}
},
sent: {
"$reduce": {
"input": "$linksLookup",
"initialValue": 0,
"in": {
"$add": [
"$$value",
{
"$cond": {
"if": {
$eq: [
"$$this.src",
"$name"
]
},
"then": "$$this.value",
"else": 0
}
}
]
}
}
}
}
}
])
這是Mongo游樂場供您參考。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/418491.html
標籤:
