web-dev-qa-db-ja.com

MongoDB:特定のフィールドのみを更新します

(入力された)MongoDBコレクションの行をC#ドライバーで更新しようとしています。タイプ_MongoCollection<User>_の特定のコレクションのデータを処理するとき、コレクションから機密データ(ソルト、パスワードハッシュなど)を取得することを避ける傾向があります。

現在、Userインスタンスを更新しようとしています。ただし、最初から機密データを実際に取得したことはないため、変更を適用して新しいデータをに送信する前に、取得したモデルインスタンスでこのデータはdefault(byte[])になると思います(私が知る限り)。コレクション。

たぶん、MongoDB C#ドライバーで、_User.PasswordHash_や_User.PasswordSalt_などの特定のプロパティを更新せずにMongoCollection<T>.Save(T item)を使用する方法を監視していますか?最初に完全なレコードを取得し、そこで「安全な」プロパティを更新して、書き戻す必要がありますか?または、更新から特定のフィールドを除外するための素晴らしいオプションはありますか?

前もって感謝します

10
Manny

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を使用すると、既存のレコードのどのフィールドを変更するかを正確に指定し、残りをそのままにしておくことができます。

あなたは例を見ることができます ここ

既存のレコードから必要なのはその_idだけです。2つのシークレットフィールドをロードしたり、POCOオブジェクトにマップし直したりする必要はありません。

16
Nuk Nuk San

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);
3
user6356311

同じ問題があり、すべてのタイプに1つのジェネリックメソッドが必要で、Reflectionを使用して独自の実装を作成したくなかったため、次のジェネリックソリューションになりました(すべてを1つのメソッドに表示するように簡略化)。

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を使用してカスタム更新メソッドを記述します

    追伸:明らかにMongoDB .Net Driverによって実装されているはずですが、ドキュメントのどこにも見つかりませんでした。間違った見方をしているだけかもしれません。

1
Vitaly

mongodbの値を更新する方法はたくさんあります。

以下は、mongodbコレクションのフィールド値を更新するために選択する最も簡単な方法の1つです。

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;    
        }

これを希望するとあなたを助けます:)

1
Vikash Pandey