2012-06-20 95 views
3

我無法找到正確的語法來替換嵌套在集合內幾個級別深度的對象數組。我的偏好是更新個別屬性,但是從閱讀下面的鏈接看來,替換整個陣列是最好的選擇。更新多級嵌入式mongo陣列

https://jira.mongodb.org/browse/SERVER-831

所以,我有以下類爲例:

public class Parent 
    { 
     public ObjectId _id { get; set; } 
     public string Firstname { get; set; } 
     public string Lastname { get; set; } 
     public Collection<Child> Children { get; set; } 
    } 

    public class Child 
    { 
     public ObjectId _id { get; set; } 
     public string Firstname { get; set; } 
     public string Lastname { get; set; } 
     public Collection<Pet> Pets { get; set; } 
    } 

    public class Pet 
    { 
     public string Name { get; set; } 
    } 

使用下面的代碼創建一個家長,添加一些兒童,並添加一個寵物的孩子之一。

// Construct Objects 
Parent parent = new Parent() { _id = new ObjectId("4f979621682dbc1a8cefecb1") }; 

Collection<Child> children = new Collection<Child>(); 
Collection<Pet> pets = new Collection<Pet>(); 

children.Add(new Child() 
    { _id = new ObjectId("4f979621682dbc1a8cefecaf"), 
     Firstname = "Child", 
     Lastname = "One" }); 
children.Add(new Child() 
    { _id = new ObjectId("4f979621682dbc1a8cefecb0"), 
     Firstname = "Child", 
     Lastname = "Two" }); 
pets.Add(new Pet() { Name = "Fishy" }); 

parent.Children = children; 
parent.Children[0].Pets = pets; 

// Connect to Mongo 
var server = MongoServer.Create("mongodb://localhost/?safe=true"); 
var db = server.GetDatabase("test"); 

// Insert into parent collection 
MongoCollection<Parent> parents; 
parents = db.GetCollection<Parent>("parents"); 
parents.Insert<Parent>(parent, MongoDB.Driver.SafeMode.True); 

這成功地插入的對象,生成以下JSON結果:

{ "_id" : ObjectId("4f979621682dbc1a8cefecb1"), 
    "Firstname" : null, 
    "Lastname" : null, 
    "Children" : 
    [ 
     { 
      "_id" : ObjectId("4f979621682dbc1a8cefecaf"), 
      "Firstname" : "Child", 
      "Lastname" : "One", 
      "Pets" : 
      [ 
       { 
        "Name" : "Fishy" 
       } 
      ] 
     }, 
     { 
      "_id" : ObjectId("4f979621682dbc1a8cefecb0"), 
      "Firstname" : "Child", 
      "Lastname" : "Two", 
      "Pets" : null 
     } 
    ] 
} 

更新個人文檔元素也似乎是一個簡單的過程,並用下面的代碼成功地起作用。

// Change children's name 
var query = new QueryDocument { { "Children._id", new ObjectId("4f979621682dbc1a8cefecaf") } }; 
var update = Update.Set("Children.$.Firstname", "Something"); 
parents.Update(query, update); 

現在我不能解決的問題是如何替換Pets數組。下面的代碼不會編譯爲Update.Set不接受集合。

// Change pets information 
pets[0].Name = "Fishy2"; // change to pet 
pets.Add(new Pet() { Name = "Doggy" }); // add new pet 

query = new QueryDocument { { "Children._id", new ObjectId("4f979621682dbc1a8cefecaf") } }; 
update = Update.Set("Children.$.Pets", pets); 
parents.Update(query, update); 

那麼什麼是最好的過程,可以讓我更新寵物數組中的細節?

+0

。使用通用集合將會更容易! –

+0

@Rhhound:他正在使用一個通用集合。你指的是什麼? –

回答

2

以下是您正在查找的代碼:您需要將BsonArray傳遞給Update.Set值。要創建該數組,您需要將每個「寵物」包裝在BsonDocumentWrapper中,以便序列化庫知道如何適當地序列化它們。

var query = new QueryDocument { { "Children._id", new ObjectId("4f979621682dbc1a8cefecaf") } }; 
var petDocuments = BsonDocumentWrapper.CreateMultiple(pets); 
var petArray = new BsonArray(petDocuments); 
var update = Update.Set("Children.$.Pets", petArray); 
parents.Update(query, update); 
+0

輝煌。謝謝克雷格。作品一種享受。 –

0
> db.Questions.find().pretty() 
{ 
     "Answers" : [ 
       { 
         "_id" : ObjectId("52ae4946e1df9e1b10e1f6e1"), 
         "Text" : "ans", 
         "Comments" : [ ] 
       } 
     ], 
     "CreatedDate" : ISODate("2013-12-16T00:28:47.790Z"), 
     "QuestionText" : "test", 
     "QuestionTitle" : "test", 
     "Tag" : "test", 
     "UserID" : "singleuserid_777", 
     "_id" : ObjectId("52ae493fe1df9e1b10e1f6e0") 
} 
> 

現在,如果我需要更新的問題收集回答陣列註釋數組,那麼究竟爲什麼你用血淋淋的數組做到這一點我的C#.NET代碼將

base.GetContext.Collection.Find(Query.EQ("Answers._id", ObjectId.Parse(Id))).Collection.Update(Query.EQ("Answers._id", ObjectId.Parse(Id)),MongoDB.Driver.Builders.Update.PushWrapped("Answers.$.Comments", comm));