0

我在流星中使用MongoDB聚合。在流星中使用MongoDB聚合時無法獲得正確的結果

在數據庫中的項目是這樣的:

//物品1

{ 
    products: { 
    aaa: 100, 
    bbb: 200 
    } 
} 

// ITEM2

{ 
    products: { 
    aaa: 300, 
    bbb: 400 
    } 
} 

我管線看起來像這樣

let pipeline = [{ 
    $limit: 10 
    }, { 
    $group: { 
     _id: { 
     // … 
     }, 
     total: { 
     $sum: "$products.aaa" 
     } 
    } 
    }]; 

它正在完美工作克拉。但是,當我改變我的數據庫結構,這

//物品1

{ 
    products: [ 
    {code: "aaa", num: 100}, 
    {code: "bbb", num: 200} 
    ] 
} 

// ITEM2

{ 
    products: [ 
    {code: "aaa", num: 300}, 
    {code: "bbb", num: 400} 
    ] 
} 

我得到了total結果總是0,我想我的管道是錯誤的。請參閱裏面的評論:

let pipeline = [{ 
    $limit: 10 
    }, { 
    $group: { 
     _id: { 
     // … 
     }, 
     total: { 
     $sum: "$products.0.num" // Neither this nor "$products[0].num" works 
     } 
    } 
    }]; 

那麼我該如何正確書寫它?由於

回答

1

隨着MongoDB的3.2(這將不與流星捆綁的服務器,但指出使用一個單獨的服務器實例阻止你而實際上將被推薦。)您可以使用$arrayElemAt$map

let pipeline = [ 
    { "$limit": 10 }, 
    { "$group": { 
     "_id": { 
     // … 
     }, 
     "total": { 
     "$sum": { "$arrayElemAt": [ 
      { "$map": { 
       "input": "$products", 
       "as": "product", 
       "in": "$$product.num" 
      }}, 
      0 
     ]} 
     } 
    }} 
]; 

對於舊版本,在使用$unwind進行處理後,使用「two」$group階段和$first運營商。而這僅僅是爲「第一」指標值:

let pipeline = [ 
    { "$limit": 10 }, 
    { "$unwind": "$products" }, 
    { "$group": { 
     "_id": "$_id",  // The document _id 
     "otherField": { "$first": "$eachOtherFieldForGroupingId" }, 
     "productNum": { "$first": "$products.num" } 
    }}, 
    { "$group": { 
     "_id": { 
     // … 
     }, 
     "total": { 
     "$sum": "$productNum" 
     } 
    }} 
]; 

因此,在後一種情況下,你$unwind後,你只是想用$first從數組中獲得了「第一」的指標,並且它也將使用從原始文檔中獲取想要用作分組鍵的一部分的每個字段。在$unwind之後,將爲每個陣列成員複製所有元素。

在前一種情況下,$map只是爲每個陣列成員提取"num"值,然後$arrayElemAt只是檢索想要的索引位置。

自然,MongoDB 3.2的更新方法更好。如果你想要另一個數組索引,那麼你需要反覆從數組中獲取$first元素,並保持從數組結果中過濾出來,直到達到所需的索引。

因此儘管在早期版本中可能,但要實現這一目標還有很多工作要做。

+0

我的流星正在使用mongo 2.6.7。所以我用第二種方法。起初我不明白'$ eachOtherFieldForGroupingId'的作用,但現在我明白了!謝謝,作品完美! –

+0

@HongboMiao對不起,如果這是一個抽象的術語,但也有聲明*「......並且它也將被用於從原始文檔中獲取想要用作分組鍵的一部分的每個字段。「*放在那裏以澄清。最常見的聚合管道錯誤是人們錯過了如果您想引用在'$ project'或'$ group'之後的一個字段中,那麼只有實際上要求第一次使用才能「發出」的字段實際上將可用。 –

+0

@HongboMiao爲了將來的參考,您會得到一個更清晰的例如,如果實際包含示例文檔和代碼的** full **表達式而不是'_id「:{...}'這是模棱兩可的,並且實際上並不顯示引用的字段,還要聲明」事實「 ,*「......它不會與流星捆綁在一起的服務器,但有一點要注意停止使用單獨的服務器實例」*,雖然它可能「簡單」,但只需在內部啓動帶有「流星」的捆綁服務器您的項目正在開發中,真實世界的部署將使用外部服務器你應該習慣這一點。 –