简体   繁体   中英

how to replace the entire array using MongoDB c# driver

Say, the existing document in DB is like this:

{
  "_id": "1",
  "settings": {
     "languages": [ "english", "french" ]
  }
}

Now I want to update the document to this:

{
  "_id": "1",
  "settings": {
     "languages": [ "korean", "german" ]
  }
}

I tired this following code:

var lan = new List<string> { "finish", "russian", "korean" }   
collection.UpdateOne(
Builders<MyObject>.Filter.Eq("_id", "1"), 
Builders<MyObject>.Update.Set("settings.languages", lan));

But got following exception:

MongoDB.Bson.Serialization.Serializers.EnumerableInterfaceImplementerSerializer 2[System.Collections.Generic.List 1[System.String],System.String]' cannot be converted to type 'MongoDB.Bson.Serialization.IBsonSerializer`1[System.String]

I also tried using BsonArray to initialize the new languages array:

var bsonArray = new BsonArray
{
    "korean",
    "german"
};

collection.UpdateOne(
Builders<MyObject>.Filter.Eq("_id", "1"), 
Builders<MyObject>.Update.Set("settings.languages", bsonArray));

The update could be executed without error, but the languages in document is changed to:

{
  "_id": "1",
  "settings": {
     "languages": "[korean, german]"
  }
}

It becomes "[ xx, xx ]" , instead of [ "xx", "xx" ] . It is not what I expected.

You're getting that error message because you're using strongly typed builders on type MyObject which probably looks more or less like below:

public class MyObject
{
    public string _id { get; set; }
    public Settings settings { get; set; }
}

public class Settings
{
    public string[] languages { get; set; }
}

So since you have a strongly typed Builder you are getting an exception because of the type mismatch between List and Array . Two ways to fix that:

Either use .ToArray() on list to get the same type as the one you have in your MyObject :

var lan = new List<string> { "finish", "russian", "korean" };
collection.UpdateOne(
    Builders<MyObject2>.Filter.Eq("_id", "1"),
    Builders<MyObject2>.Update.Set("settings.languages", lan.ToArray()));

or skip the type validation using BsonDocument class:

var collection = mydb.GetCollection<BsonDocument>("col");
var lan = new List<string> { "finish", "russian", "korean" };
collection.UpdateOne(
    Builders<BsonDocument>.Filter.Eq("_id", "1"),
    Builders<BsonDocument>.Update.Set("settings.languages", lan));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM