我在 mongdo DB 上有三个文档,如下例所示(祖文档、父文档和子文档)。我希望使用 C# mondoDB 驱动程序将对象包含在结果中。场景是如果孙子没有属性/值(例如 gprop2,fprop2 ),那么它将从父/子父级获取属性/值,但同时如果所有文档都具有相同的属性(例如“cprop1”) ,那么毕业生孩子将覆盖来自父母和毕业生父母的值。毕业生孩子也可以拥有自己的属性(“sprop2”),该属性应包含在最终结果中。我通过手动检查/复制属性/值给子项获得了最终结果,但我正在寻找有效的解决方案。有没有办法在.NET core中使用C# mongoDb驱动来实现它?
祖父母医生
{
"cprop1": "gval1",
"gprop2": "gval2"
"gppcrop2": "gpcval22",
"assets" : [
{
"gasset1": "gassetVal1",
"gcasset1": "gcassetVal1"
},......
]
}
家长文档
{
"cprop1": "fval1",
"fprop2": "fval2",
"gppcrop2": "gpcval33",
"assets" : [
{
"passet1": "passetVal1",
"gcasset1": "gcassetVal2"
},.......
]
}
儿童医生
{
"cprop1": "sval1",
"sprop2": "sval2",
"assets" : [
{
"sasset1": "sassetVal1",
"gcasset1": "gcassetVal3"
},..........
]
}
最终结果
{
"cprop1": "sval1",
"gprop2": "gval2",
"fprop2": "fval2",
"gppcrop2": "gpcval33",
"sprop2": "sval2",
"assets": [
{
"gasset1": "gassetVal1",
"passet1": "passetVal1"
"sasset1": "sassetVal1",
"gcasset1": "gcassetVal3"
},....
]
}
您可以使用合并方法来完成此操作。
static void Main(string[] args)
{
BsonDocument gp = new BsonDocument("cprop1", "gval1").Add("gprop2", "gval2").Add("gppcrop2", "gpcval22");
BsonDocument parent = new BsonDocument("cprop1", "fval1").Add("fprop2", "fval2").Add("gppcrop2", "gpcval33");
BsonDocument child = new BsonDocument("cprop1", "sval1").Add("sprop2", "sval2");
child.Merge(parent);
child.Merge(gp);
Console.WriteLine(child.ToJson(new MongoDB.Bson.IO.JsonWriterSettings() { Indent = true }));
}
你得到了
{
"cprop1" : "sval1",
"sprop2" : "sval2",
"fprop2" : "fval2",
"gppcrop2" : "gpcval33",
"gprop2" : "gval2"
}
public async Task<ReplaceOneResult> MergeOneAsync<T>(IClientSessionHandle? session, FilterDefinition<BsonDocument> filter, T replacement, FindOptions<BsonDocument, BsonDocument> findOptions = null, ReplaceOptions replaceOptions = null, CancellationToken cancellationToken = default) where T : AbstractModel
{
var collection = GetDatabase().GetCollection<BsonDocument>(Collection);
IAsyncCursor<BsonDocument> cursor = null;
ReplaceOneResult result = null;
if (session != null)
cursor = await collection.FindAsync(session, filter, findOptions, cancellationToken);
else
cursor = await collection.FindAsync(filter, findOptions, cancellationToken);
var list = await cursor.ToListAsync();
if (list != null && list.Any())
{
var foundDoc = list.FirstOrDefault();
var docAsStr = BsonDocument.Parse(JsonConvert.SerializeObject(replacement));
foreach (var element in docAsStr) {
if (element.Name != "_id")
{
foundDoc[element.Name] = element.Value;
}
}
if (session != null)
result = await collection.ReplaceOneAsync(session, filter, foundDoc, replaceOptions, cancellationToken);
else
result = await collection.ReplaceOneAsync(filter, foundDoc, replaceOptions, cancellationToken);
}
return result;
}