MongoDB:仅更新特定字段

时间:2013-02-13 12:15:43

标签: c# mongodb mongodb-.net-driver

我正在尝试使用C#驱动程序更新(类型化)MongoDB集合中的行。处理类型MongoCollection<User>的特定集合的数据时,我倾向于避免从集合中检索敏感数据(salt,密码哈希等)

现在我正在尝试更新User实例。但是,我从来没有真正检索过敏感数据,所以我想在应用修改并将新数据提交给集合之前,检索到的模型实例中的数据default(byte[])(据我所知)

也许我在MongoDB C#驱动程序中监督一些微不足道的事情我如何在不更新MongoCollection<T>.Save(T item)User.PasswordHash等特定属性的情况下使用User.PasswordSalt?我应该首先检索完整记录,在那里更新“安全”属性,然后将其写回?或者是否有一个奇特的选择来从更新中排除某些字段?

提前致谢

4 个答案:

答案 0 :(得分:16)

Save(someValue)适用于您希望结果记录成为或传入的完整对象(someValue)的情况。

您可以使用

var query = Query.EQ("_id","123");
var sortBy = SortBy.Null;
var update = Update.Inc("LoginCount",1).Set("LastLogin",DateTime.UtcNow); // some update, you can chain a series of update commands here

MongoCollection<User>.FindAndModify(query,sortby,update); 

方法

使用FindAndModify,您可以准确指定要更改的现有记录中的哪些字段,并将其余字段单独保留。

您可以看到示例here

现有记录中唯一需要的是它的_id,2个秘密字段无需加载或映射回POCO对象。

答案 1 :(得分:3)

可以在Where语句中添加更多标准。像这样:

var db = ReferenceTreeDb.Database;
var packageCol = db.GetCollection<Package>("dotnetpackage");
var filter = Builders<Package>.Filter.Where(_ => _.packageName == packageItem.PackageName.ToLower() && _.isLatestVersion);
var update = Builders<Package>.Update.Set(_ => _.isLatestVersion, false);
var options = new FindOneAndUpdateOptions<Package>();
packageCol.FindOneAndUpdate(filter, update, options);

答案 2 :(得分:1)

有很多方法可以更新mongodb中的值。

以下是我选择更新mongodb集合中字段值的最简单方法之一。

public string UpdateData()
        {               
            string data = string.Empty;
            string param= "{$set: { name:'Developerrr New' } }";
            string filter= "{ 'name' : 'Developerrr '}";
            try
            {  
               //******get connections values from web.config file*****
                var connectionString = ConfigurationManager.AppSettings["connectionString"];
                var databseName = ConfigurationManager.AppSettings["database"];
                var tableName = ConfigurationManager.AppSettings["table"];

                //******Connect to mongodb**********
                var client = new MongoClient(connectionString);
                var dataBases = client.GetDatabase(databseName);
                var dataCollection = dataBases.GetCollection<BsonDocument>(tableName);       

                //****** convert filter and updating value to BsonDocument*******
                BsonDocument filterDoc = BsonDocument.Parse(filter);
                BsonDocument document = BsonDocument.Parse(param);

                //********Update value using UpdateOne method*****
                dataCollection.UpdateOne(filterDoc, document);                   
                data = "Success";
            }
            catch (Exception err)
            {
                data = "Failed - " + err;
            }
            return data;    
        }

希望这会对您有所帮助:)

答案 3 :(得分:0)

有同样的问题,因为我想为所有类型都有一个通用方法,并且不想使用Reflection创建我自己的实现,我最终得到以下通用解决方案(简化为在一个方法中显示所有):

Task<bool> Update(string Id, T item)
{
    var serializerSettings = new JsonSerializerSettings()
            {
                NullValueHandling = NullValueHandling.Ignore,
                DefaultValueHandling = DefaultValueHandling.Ignore
            };
    var bson = new BsonDocument() { { "$set", BsonDocument.Parse(JsonConvert.SerializeObject(item, serializerSettings)) } };
    await database.GetCollection<T>(collectionName).UpdateOneAsync(Builders<T>.Filter.Eq("Id", Id), bson);
}

注意:

  • 确保所有必须不更新的字段都设置为默认值。
  • 如果需要将字段设置为默认值,则需要使用DefaultValueHandling.Include,或为该更新编写自定义方法
  • 当性能很重要时,请使用Builders<T>.Update

    编写自定义更新方法

    P.S。:显然应该由MongoDB .Net Driver实现,但是我在文档中的任何地方都找不到它,也许我只是看错了。