4

私は2つのクラスを持っています:

public class Vote
{
    public string VoteId { get; set; }
    public string Question { get; set; }
    public List<VoteAnswer> AnswerList { get; set; }
}

と:

public class VoteOption
{
    public string OptionId { get; set; }
    public string OptionName { get; set; }
    public double VoteCount { get; set; }
}

whereとVoteOptionで a を更新/削除するにはどうすればよいですか? ドライバー使用。VoteVoteId = voteIdOptionId = optionIdC#

まず、次の方法で VoteOption を取得します。

        var v = col.FindOneAs<Vote>(Query.EQ("VoteID", voteId));
        VoteOption vo = v.AnswerList.Find(x => x.OptionId == optionId);

それにいくつかの値を設定して終了します。

vo.OptionName = "some option chose";
vo.VoteCount = 1000;

voしかし、これを更新する次のステップがわかりませんVote parent

そして、これを削除したい場合は、voその方法を教えてください!

そのようなMongoDBのデータ:

{
  "_id" : "460b3a7ff100",
  "Question" : "this is question?",
  "AnswerList" : [{
      "OptionId" : "1",
      "OptionName" : "Option 1",
      "VoteCount" : 0.0
    }, {
      "OptionId" : "2",
      "OptionName" : "Option 2",
      "VoteCount" : 0.0
    }, {
      "OptionId" : "3",
      "OptionName" : "Option 3",
      "VoteCount" : 0.0
    }
    }]
}
4

4 に答える 4

12

サブドキュメントを更新するには、これを使用できます。

var update = Update.Set("AnswerList.$.OptionName", "new").Set("AnswerList.$.VoteCount", 5);
collection.Update(Query.And(Query.EQ("_id", new BsonObjectId("50f3c313f216ff18c01d1eb0")), Query.EQ("AnswerList.OptionId", "1")), update);

プロファイラー:

"query" : { "_id" : ObjectId("50f3c313f216ff18c01d1eb0"), "AnswerList.OptionId" : "1" },
"updateobj" : { "$set" : { "AnswerList.$.OptionName" : "new", "AnswerList.$.VoteCount" : 5 } }

そして削除するには:

var pull = Update<Vote>.Pull(x => x.AnswerList, builder => builder.EQ(q => q.OptionId, "2"));
collection.Update(Query.And(Query.EQ("_id", new BsonObjectId("50f3c313f216ff18c01d1eb0")), Query.EQ("AnswerList.OptionId", "2")), pull);

プロファイラー:

"query" : { "_id" : ObjectId("50f3c313f216ff18c01d1eb0"), "AnswerList.OptionId" : "2" },
"updateobj" : { "$pull" : { "AnswerList" : { "OptionId" : "2" } } }

もう 1 つの方法は、変更された子コレクションで親ドキュメントを更新することです。

于 2013-01-14T09:03:20.627 に答える
2
// Example function for update like count add like user  using c#    
public PostModel LikeComment(LikeModel like)
{
    PostModel post = new PostModel();

    _client = new MongoClient();
    _database = _client.GetDatabase("post");
    var collection = _database.GetCollection<PostModel>("post");

    var _filter = Builders<PostModel>.Filter.And(
    Builders<PostModel>.Filter.Where(x => x.PostId == like.PostId),
    Builders<PostModel>.Filter.Eq("Comments.CommentId", like.CommentId));

    var _currentLike = collection.Find(Builders<PostModel>.Filter.Eq("PostId", like.PostId)).FirstOrDefault().Comments.Find(f => f.CommentId == like.CommentId).Like;

    var update = Builders<PostModel>.Update.Set("Comments.$.Like", _currentLike + 1);
    collection.FindOneAndUpdate(_filter, update);

    var addUser = Builders<PostModel>.Update.Push("Comments.$.LikeUsers", like.UserId);
    collection.FindOneAndUpdate(_filter, addUser);

    var _findResult = collection.Find(_filter).FirstOrDefault();

    return _findResult;
}
于 2016-11-17T12:23:32.950 に答える
1

遅い答えですが、これは文字列なしで行う方法です。プロパティ コードを変更すると、コンパイルされません。本番コードでの式の試みの使用は初めてです! 彼らは素晴らしいです!

モデル:

class Phone
{
  public string _id { get; set; }
  public string Name { get; set; }
  public DateTime DateCreated { get; set; }

            // Contain multiple lines as subdocument
  public List<Line> Lines { get; set; }
}

class Line
{
   public string Name { get; set; }
   public string PhoneNumber { get; set; }
}

コード: これは、文字列に依存せずに更新ステートメントを作成する方法です。

var update = new UpdateDocument<Phone>();

// set filter
update.SetFilter(x => x._id == "123456789");

update.AddValueToUpdate(p => p.Name, "New Name");
update.AddValueToUpdate(p => p.Lines[0].Name, "Line 1");
update.AddValueToUpdate(p => p.Lines[1].Name, "Line 2");
update.AddValueToUpdate(p => p.DateCreated, DateTime.UtcNow);


var updateQuery = update.Build();

これはこれを作成します!これは、更新を行うために mondo に渡す必要があるものです。

{ "_id" : "123456789" },
{$set:
  {"Name":"New Name","Lines.0.Name":"Line 1","Lines.1.Name":"Line 2","DateCreated":ISODate("2021-04-30T16:04:59.332Z")}
}

そのコードをここで機能させたい場合は、ヘルパー クラスがあります。


using MongoDB.Bson;
using System.Linq.Expressions;
using MongoDB.Bson.Serialization;

class UpdateDocument<T>
{
    /// <summary>
    ///     _id of document to update. 
    /// </summary>
    private string _filter;

    /// <summary>
    ///     Example:
    ///     FirstName, Antonio
    ///     Education.Elementary.Year, 2004
    /// </summary>
    private List<KeyValuePair<string, object>> _valuesToUpdate { get; set; } = new List<KeyValuePair<string, object>>();

    public void SetFilter(Expression<Func<T, bool>> filterDefinition)
    {
        var documentSerializer = BsonSerializer.SerializerRegistry.GetSerializer<T>();
        var where = Builders<T>.Filter.Where(filterDefinition).Render(documentSerializer, BsonSerializer.SerializerRegistry);
        _filter = where.ToJson();
    }

    public void AddValueToUpdate(string name, object value)
    {
        _valuesToUpdate.Add(new KeyValuePair<string, object>(name, value));
    }

    public void AddValueToUpdate(Expression<Func<T, object>> name, object value)
    {
        var memberExpression = name.Body as MemberExpression;
        if (memberExpression == null)
        {
            var unaryExpression = name.Body as UnaryExpression;
            if (unaryExpression != null && unaryExpression.NodeType == ExpressionType.Convert)
                memberExpression = unaryExpression.Operand as MemberExpression;
        }

        var result = memberExpression.ToString();
        result = result.Substring(result.IndexOf('.') + 1);

        if (result.Contains("get_Item"))
            result = Regex.Replace(result, @"(?x) get_Item \( (\d+) \)", m => $"{m.Groups[1].Value}");

        AddValueToUpdate(result, value);
    }

    public string Build()
    {
        if (_valuesToUpdate.Any() == false)
        {
            // nothing to update
            return null;
        }

        /*
update({ 
_id: 7, 
"comments._id": ObjectId("4da4e7d1590295d4eb81c0c7")
},{
$set: {"comments.$.type": abc}
}, false, true
);
            */

        StringBuilder sb = new StringBuilder();

        sb.Append(_filter);
        sb.Append(',');

        sb.Append("{");
        {
            sb.Append("$set:{");
            foreach (var item in _valuesToUpdate)
            {
                sb.Append('"');
                sb.Append(item.Key);
                sb.Append('"');
                sb.Append(':');

                var value = BsonExtensionMethods.ToJson(item.Value);
                sb.Append(value);
                sb.Append(',');
            }
            // remove last comma
            sb.Length--;
            sb.Append('}');
        }
        sb.Append("}");

        return sb.ToString();




    }


}
于 2021-04-30T16:09:12.903 に答える