[英]How can I delete nested array element in a mongodb document with the c# driver
[英]C# mongodb delete document from doubly nested array
首先,我找到了python和mongo shell的很多解决方案,但是C#没有,这就是我创建这个线程的原因。
数据库有一个项目列表,项目有一个文件列表,文件列表有一个翻译列表。 任务是从翻译数组中删除具有给定 ID 的翻译文档。 我们知道所有信息来查找文档,例如项目的_id、文件的_id和翻译的ID。
这是它的外观:
[{
"_id": "62e237a1d866d82c881629a1",
"Name": "test92",
"PrimarySourceLanguage": "eng",
"PivotSourceLanguage": "hun",
"TargetLanguages": [
"prs",
"fre-BE",
"fre-CH"
],
"Files": [
{
"segments": [
],
"Name": "smallBatch_test.json",
"_id": "f7b02afb-ec62-439b-be6d-403b8f1434ff",
"ImportDate": {
"$date": {
"$numberLong": "1658992556090"
}
},
"TargetLanguages": null,
"Translation": [
{
"ID": "e5e09f84-64d7-40a4-87f7-a90f5a956c32",
"SourceLanguage": "eng",
"TargetLanguage": "prs",
"TranslatedString": null,
"ProjectGuid": "62e237a1d866d82c881629a1",
"FileGuid": "f7b02afb-ec62-439b-be6d-403b8f1434ff",
"Status": "Translation deleted"
},
{
"ID": "8d4ca52c-0063-474a-94db-fd2d8b1f2cee",
"SourceLanguage": "eng",
"TargetLanguage": "prs",
"TranslatedString": "Boci múú",
"ProjectGuid": "62e237a1d866d82c881629a1",
"FileGuid": "f7b02afb-ec62-439b-be6d-403b8f1434ff",
"Status": null
},
{
"ID": "2929dc9e-5254-4093-93bc-fbcdcb265ea7",
"SourceLanguage": "eng",
"TargetLanguage": "prs",
"TranslatedString": "Bocikaaa",
"ProjectGuid": "62e237a1d866d82c881629a1",
"FileGuid": "f7b02afb-ec62-439b-be6d-403b8f1434ff",
"Status": "Translated"
}
]
}
],
"TemplateGuid": {
"$binary": {
"base64": "AAAAAAAAAAAAAAAAAAAAAA==",
"subType": "03"
}
},
"Deadline": {
"$date": {
"$numberLong": "1659165300000"
}
},
"TMs": [
null
],
"TBs": [
null
],
"Domain": null,
"Client": null
}]
我尝试使用 pullfilter 或使用带有 Pull 命令的更新,但它们都不起作用:(
以下实现假设翻译 id 是全局唯一的,因此没有两个文件具有相同 id 的翻译。 它使用带有映射文件的聚合管道的更新,以便只有翻译包含在 ID 中,而不是要删除的 ID:
db.collection.update({
_id: "62e237a1d866d82c881629a1"
},
[
{
"$set": {
"Files": {
"$map": {
"input": "$Files",
"as": "file",
"in": {
"$mergeObjects": [
"$$file",
{
Translation: {
"$filter": {
"input": "$$file.Translation",
"as": "translation",
"cond": {
"$ne": [
"$$translation.ID",
"e5e09f84-64d7-40a4-87f7-a90f5a956c32"
]
}
}
}
}
]
}
}
}
}
}
])
此Playground包含示例数据的简化版本并包含普通更新。
缺点是 C# 中对聚合管道更新的支持并未涵盖 MongoDB 提供的所有选项。 但是您可以使用BsonDocument
来定义管道(我假设 model class 称为Project
):
var filter = Builders<Project>.Filter
.Eq(x => x.Id, "62e237a1d866d82c881629a1");
var pipeline = new EmptyPipelineDefinition<Project>()
.AppendStage(new BsonDocument("$set",
new BsonDocument("Files",
new BsonDocument("$map",
new BsonDocument
{
{ "input", "$Files" },
{ "as", "file" },
{ "in",
new BsonDocument("$mergeObjects",
new BsonArray
{
"$$file",
new BsonDocument("Translation",
new BsonDocument("$filter",
new BsonDocument
{
{ "input", "$$file.Translation" },
{ "as", "translation" },
{ "cond",
new BsonDocument("$ne",
new BsonArray
{
"$$translation.ID",
"e5e09f84-64d7-40a4-87f7-a90f5a956c32"
}) }
}))
}) }
}))),
BsonDocumentSerializer.Instance)
.As<Project, BsonDocument, Project>();
var update = Builders<Project>.Update.Pipeline(pipeline);
var result = await coll.UpdateOneAsync(filter, update);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.