2011-06-03 40 views
2

我正在嘗試將列表推送到文檔的子文檔。 如果我插入的BsonDocument它的工作原理如下圖所示只是一個單一的對象:如何將List <>推送到mongodb中的子文檔中?

BsonDocument subdoc = new BsonDocument { 
       { "_id", ObjectId.GenerateNewId()}, 
       {"name", "Mr Bob"} 
       }; 

       var query = Query.EQ("_id", new ObjectId("1234..")); 
       var upd = Update.Push("members", subdoc); <-works 
       groups.Update(query, upd); 

但我需要推列表。我得到這個異常:

"WriteStartArray cannot be called when State is: Initial" 

這是一個錯誤的代碼:

List<BsonDocument> newMembers = new List<BsonDocument>(); 
BsonDocument subdoc = new BsonDocument { 
        { "_id", ObjectId.GenerateNewId()}, 
        {"name", "Mr Bob"} 
        }; 
newMembers.Add(subdoc); 
subdoc = new BsonDocument { 
        { "_id", ObjectId.GenerateNewId()}, 
        {"name", "Mr Tom"} 
        };     
newMembers.Add(subdoc); 

var query = Query.EQ("_id", new ObjectId(id)); 
var upd = Update.Push("members", newMembers.ToBsonDocument()); <- EXCEPTION 
groups.Update(query, upd); 

在插入之後,我會看到:

groups: 
{ 
    _id:1, 
    members:[ 
    { 
     _id:1, 
     name: "Mr Bob" 
    }, 
    { 
     _id:1, 
     name: "Mr Tom" 
    } 
    ] 
} 

回答

1

由於newMembers已經是BsonDocument名單你不需要再次將其轉換爲BsonDocument。

如果你想推一個以上的文件,你需要使用一個嵌套的數組$pushAll

var upd = Update.PushAll("members", newMembers.ToArray()); 

在,如果你需要一些類,你需要在每個項目轉換BsonDocument的推列表項目情況:

讓我們說newMembers是成員類的目錄,然後如果你需要按下列表以嵌套數組,你應該做這樣的事情:

var upd = Update.PushAll("members", newMembers.Select(x=> x.ToBsonDocument()).ToArray()); 

更新:

  1. 爲了使子文檔不是唯一的,你可以創建algoritm,將產生來自同一用戶名相同的ID相同的用戶名。大多數簡單的算法可以用下劃線替換所有的空格,並使ToLower()。
  2. 另一種方法使用$slice加載嵌入數組並檢查每個子文檔的唯一性。
+0

有沒有辦法檢查重複?其中一個新條目的名稱=「Mr Bob」已存在於子文檔中。有沒有辦法像$ addToSet一樣檢查它? – kheya 2011-06-03 21:05:38

+0

@Projapati:沒有辦法用'push'來完成。爲什麼不使用$ addToSet? – 2011-06-03 21:10:18

+0

就像一個魅力。我必須添加.ToBsonDocument()作爲w/o它,它會給出語法錯誤。我認爲關鍵是ToArray()。謝謝安德魯。 – kheya 2011-06-03 22:00:15

相關問題