使用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 = voteId
和OptionId = optionId
的Vote
中更新/删除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
}
}]
}
要更新子文档,可以使用以下命令:
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();
}
}