2014-02-28 45 views
0

如何獲得內部數組子文檔元素的數量,以及如何在MongoDB中得到一個數組裏面每個索引子文檔元素的數量和更新的子文檔的關鍵 - 在陣列子文檔(MongoDB中)

對於例如更新子文檔的關鍵,以下是存儲在MongoDB的整個文檔:

{ 
    "CompanyCode" : "SNBN", 
    "EventCode" : "ET00008352", 
    "EventName" : "Sunburn Presents Avicii India Tour", 
    "TktDetail" : [ 
     { 
      "Type" : "Category I", 
      "Qty" : { 
       "10-Dec" : { 
        "value" : 58 
       }, 
       "11-Dec" : { 
        "value" : 83 
       }, 
       "12-Dec" : { 
        "value" : 100 
       } 
      } 
     }, 
     { 
      "Type" : "Category II", 
      "Qty" : { 
       "10-Dec" : { 
        "value" : 4 
       }, 
       "11-Dec" : { 
        "value" : 7 
       }, 
       "12-Dec" : { 
        "value" : 8 
       } 
      } 
     }, 
     { 
      "Type" : "PRICE LEVEL 1", 
      "Qty" : { 
       "11-Dec" : { 
        "value" : 2 
       } 
      } 
     }, 
     { 
      "Type" : "CatIV", 
      "Qty" : { 
       "18-Dec" : { 
        "value" : 20 
       } 
      } 
     } 
    ], 
    "TransDate" : [ 
     "10-Dec-2013", 
     "11-Dec-2013", 
     "12-Dec-2013", 
    ], 
    "VenueCode" : "SNBN", 
    "VenueName" : "Sunburn", 
    "_id" : ObjectId("52452db273b92012c41ad612") 
} 

這裏TktDetail是一個數組,內部有是包含多個元素數量subdoc的,我想知道如何讓每個元素索引中的數量算什麼?

例如,TktDetail數組的第0個索引包含1個數量的子數據庫,其中還有一個元素數爲3,而第3個索引在Qty子數據中的元素數爲1。

如果我想更新subdoc的關鍵一樣,我想從「10日 - 12月」到「10日 - 12月2013」​​更新數量日期,怎麼可能?

在此先感謝,尋找儘快答覆..

+0

有人(不是我,還)只是downvoted你,因爲你沒有格式化喜歡的網站數據塊** **問你做。另外**不要泄露**以粗體顯示所有內容。注意未來。但**現在**你**可能會得到一些幫助。 –

+0

現在。你的問題是(澄清)你想要更新數量下的子文件中的值。對? –

+0

感謝尼爾爲我未來的筆記提供建議。我不想更新內部數量值字段,我想更新內部數量的鍵名存儲在陣列TktDetail,用於例如:如果是「10 - 12月」,那麼我想更新爲「10 - 癸2013" 。 –

回答

0

所以這裏的第一件事情是,你居然問問題,是「我如何才能Qty下的項目數?」「我如何更改名稱?」。現在雖然通常無關,但我會把它們當作同一件事。

你需要做的是改變你的模式並在這樣做,我會讓你得到項目的數量,我會鼓勵你也改變這些字段名稱。具體來說,你需要這樣的模式:

"TktDetail" : [ 
    { 
     "Type" : "Category I", 
     "Qty" : [ 
      { "date": ISODate("2013-12-10T00:00:00.000Z") , "value" : 58 }, 
      { "date": ISODate("2013-12-11T00:00:00.000Z"), "value" : 83 }, 
      { "date": ISODate("2013-12-01T00:00:00.000Z"), "value" : 100 }, 
     ] 
    }, 

所有血淋淋的細節是my answer here到類似的問題。但問題主要是,當你在路上使用子文檔你有你破壞你做這個有意義的查詢操作的機會,因爲在每一個元素讓你必須指定完整路徑到那裏。

answer有更多詳細信息,但此案是你真正想要的數組。權衡,這是一個有點難以更新,特別是考慮到你有嵌套的數組,但它是一個更容易添加和容易查詢。

此外,和相關,更改日期爲日期和而不是字符串。這些字符串,不好,用於MongoDB內部的比較。將它們設置爲適當的BSON日期(注意我將它們剪切到了一天的開始),您可以比較和查詢範圍並執行有用的操作。您的應用程序代碼將很高興,因爲驅動程序將返回一個實際的日期對象,而不是您必須「雙向操作」的東西。

所以一旦您通過閱讀,理解和執行這一點,上計數:

db.collection.aggregate([ 

    // Unwind the TktDetail array to de-normalize 
    {"$unwind": "$TktDetail"}, 

    // Also Unwind the Qty array 
    {"$unwind": "$Qty" }, 

    // Get some group information and count the entries 
    {"$group": { 
     "_id": { 
      "_id": "$_id, 
      "EventCode": "$EventCode", 
      "Type": "$TktDetail.Type" 
     }, 
     "Qty": {"$sum": 1 } 
    }}, 

    // Project nicely 
    {"$project": { 
     "_id": 0, 
     "EventCode": "$_id.EventCode", 
     "Type: "$_id.Type", 
     "Qty": 1, 
    }}, 

    // Let's even sort it 
    {"$sort": { "EventCode": 1, "Qty" -1 }} 

]) 

所以這使我們能夠通過Type與得到計數的項目Qty每個EventCodeQty訂購最高到最低。

這是不可能在無負載的電流模式和遍歷在代碼中的每個文件。

所以有此情形。現在,如果你想忽略這,只是去改變子文檔鍵名,那麼你就需要做刪除鍵和底層文件和更換新的密鑰名稱,使用更新:

db.collection.update(
    { EventCode: "ET00008352"}, 
    { $unset:{ "TktDetail.0.Qty.10-Dec": "" }} 
) 

db.collection.update(
    { EventCode: "ET00008352"}, 
    { $set:{ "TktDetail.0.Qty.10-Dec-2013": { value: 58 } }} 
) 

而你需要做的是爲你擁有的每項目。

因此,您要麼進行模式轉換,要麼有其他的批號,以便更改密鑰。至於我自己,我會做正確,只有做到這一點一次所以我沒有碰到一個問題後。

+0

我真的很感激ü烏拉圭回合的答案,但其中u問我改變收集的架構的第一個解決方案,將在今後的創建問題,同時使用$(位置操作)更新,因爲它不支持大於1級和數量將在第二級,這就是我把它作爲一個subdoc而不是嵌套數組對待它的原因。 –

+0

其次是已知的解決方案,我不能使用,因爲我想遍歷數量而不知道鍵名並更新它。 –

+0

@SurajMishra我很清楚位置更新的問題,因此我所說的是,這可能有點困難,但並非不可能。如果是Anything,那麼在這個結構中**應該被視爲一個*子文檔*的唯一項目就是'TktDetail'部分,這使得一些其他操作更加困難,但是消除了位置更新問題。這是最小的路徑問題,因此是最好的地方。即使你知道你要用$ set和$ unset做什麼,也沒有其他方法**。如果你需要更好的解釋結構,我可以做到這一點。 –