1

我是mongoDB的新手,並且難以得到聚集流水線的頭像。MongoDB聚合管道問題

我已經創建了一個數據庫,保存有關我的股票交易的信息。在從我的投資組合集合減少的一個版本的文檔看起來有點像這樣

{ 
    "date" : 2015-12-31T15:50:00.000Z, 
    "time" : 1550, 
    "aum" : 1000000, 
    "basket" :[ 
    { 
    "_id" : "Microsoft", 
    "shares" : 10, 
    "price" : 56.53, 
    "fx"  : 1.0 
    }, 
    . 
    . 
    . 
    { 
    "_id" : "GOOG.N", 
    "shares" : 20, 
    "price" : 759.69, 
    "fx"  : 1.0 
    } 

]

所以,每一天,我跟蹤我的管理資產(AUM)和所有的列表我持有目前的價位。我需要做的是計算投資組合的每日淨暴露量和總暴露量,以百分比表示。網曝無非是:

sum(shares*price*fx)/aum

在所有股票。毛曝光是:

abs(shares*price*fx)/aum

(負的位置是指短的位置)。我需要使用聚合框架將其作爲單個查詢來完成。我已經嘗試過多次查詢,但沒有一個看起來很清晰,我只是在黑暗中漫步。任何人都可以提供指導嗎?

我的查詢看起來像這樣

db.strategy.aggregate(

    // Pipeline 
    [ 
    // Stage 1 
    { 
     $project: { 
     "_id": 0, 
     "date":1, 
     "time":1, 
     "aum":1, 
     "strategyName":1, 
     "gExposure": {$divide: ["$grossExposure","$aum"]} 
     } 
    }, 

    // Stage 2 
    { 
     $group: { 
     _id :{ date:"$date",time:"$time",strategyName:"$strategyName"}, 
     grossExposure: { $sum: { $abs: {$multiply: [ "$basket.sysCurShares","$basket.price","$basket.fx" ] } }} 
     } 
    }, 

    // Stage 3 
    { 
     $sort: { 
     "_id.date": 1, "_id.time": 1, "_id.strategyName": 1 
     } 
    } 

    ] 
); 

查詢運行,但計算出的值爲零。我的預測沒有像我期望的那樣工作,因爲我希望將所有數據拼湊成二維表格。

+1

多所社區傾斜,以幫助更多的,如果你能證明什麼你已經嘗試過了,不管它是否工作或不工作。你能顯示你試過的查詢嗎? – chridam

+0

我同意。我已經添加了我的當前嘗試 –

+0

只需確認,第一個「$ project」管道中的$ grossExposure字段是預先計算的字段,因爲它不在原始文檔模式中,或者這是您的概念掙扎着? – chridam

回答

1

由於籃領域是一個數組,你需要使用$unwind運行$group合計操作之前將其壓平。另外,在保持管線之前的曝光的情況下,創建一個新的字段。從以前的嘗試繼續,你可以試試下面的管道:

db.strategy.aggregate([ 
    { "$unwind": "$basket" }, 
    { 
     "$project": { 
      "date": 1, 
      "time": 1,   
      "strategyName": 1, 
      "exposure": { 
       "$multiply": ["$basket.sysCurShares", "$basket.price", "$basket.fx"] 
      } 
     } 
    },  
    { 
     "$group": { 
      "_id": { 
       "date": "$date", 
       "time": "$time", 
       "strategyName": "$strategyName" 
      }, 
      "totalExposure": { "$sum": "$exposure" }, 
      "aum": { "$first": "$aum" } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "date": "$_id.date", 
      "time": "$_id.time",   
      "strategyName": "$_id.strategyName", 
      "netExposure": { "$divide": ["$totalExposure", "$aum"] }, 
      "grossExposure": { 
       "$abs": { "$divide": ["$totalExposure", "$aum"] } 
      } 
     } 
    }, 
    { "$sort": { "date": 1, "time": 1, "strategyName": 1 } } 
]); 
+0

非常感謝你。我會放棄並報告。顯然,我需要閱讀關於放鬆階段。 –

+0

我認爲這有效,但它看起來像總暴露率和淨暴露量的計算被降低到整數,所以我不能看到結果,因爲暴露百分比總是<1.0。有沒有一種強制結果類型的方法? –

+0

不知何故,我無法掌握公式,它是'(sum(shares * price * fx))/ aum'還是'sum((shares * price * fx)/ aum)'?有關算術運算符的更多詳細信息,請參閱[** docs **](https://docs.mongodb。com/manual/reference/operator/aggregation-arithmetic /) – chridam

0

您可以在單級做相同的MongoDB 3.4

db.strategy.aggregate([ 
{ 
    $project:{ 
     "date": 1, 
     "time": 1,   
     "strategyName": 1, 
     "netExposure":{ "$divide": [{"$reduce":{input:"$basket",initialValue:0,in:{$add:[{$multiply: ["$$this.fx","$$this.shares","$$this.price"]},"$$value"]}}}, "$aum"] }, 
     "grossExposure":{"$abs":{ "$divide": [{"$reduce":{input:"$basket",initialValue:0,in:{$add:[{$multiply: ["$$this.fx","$$this.shares","$$this.price"]},"$$value"]}}}, "$aum"] }} 
}, 
{ "$sort": { "date": 1, "time": 1, "strategyName": 1 } } 
]);