使用c#驱动程序更新/删除mongodb中的子文档

本文关键字:文档 mongodb 删除 驱动程序 更新 使用 | 更新日期: 2023-09-27 17:52:41

我有两个类:

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

如何在VoteId = voteIdOptionId = optionIdVote中更新/删除VoteOption ?使用C#驱动程序

首先我得到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
    }
    }]
}

使用c#驱动程序更新/删除mongodb中的子文档

要更新子文档,可以使用以下命令:

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" } } }
另一种方法是使用修改后的子集合更新父文档。
// 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;
}
//Delete comment
public PostModel delcomment(int postId, int commentId)
{
    _client = new MongoClient();
    _database = _client.GetDatabase("post");
    var collection = _database.GetCollection<PostModel>("post");
    var filter = Builders<PostModel>.Filter.Eq("PostId", postId);
    var update = Builders<PostModel>.Update.PullFilter("Comments",
    Builders<Comments>.Filter.Eq("CommentId", commentId));
    collection.FindOneAndUpdate(filter, update);
    var _findResult = collection.Find(filter).FirstOrDefault();
    return _findResult;
}

迟来的答案但这是如何做到没有字符串。如果修改属性代码将无法编译。第一次在生产代码中使用表达式!他们太棒了!

模型:

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();

This创建This !这就是为了执行update

,你需要传递给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();


    }

}