我在使用官方 mongodb c# 驱动程序删除数组中的文档时遇到问题。我想做的也是返回已删除的文档。
这是我的班级的样子:
public class Holder
{
public string Owner { get; set; }
public List<Card> Cards { get; set; }
}
public class Card
{
public string Id { get; set; }
public string Name { get; set; }
public string Placement { get; set; }
}
这是文档的摘录:
{
"owner": "656dd33e0300"
"cards" : [
{
"id": "s39CNzu4Na3",
"name" : "Department",
"placement" : "8a"
},
...
]
}
我的第一个想法是获取该卡,然后使用以下命令将其删除:
var filter = Builders<Card>.Filter.Eq(x => x.Id, cardId);
var res = await collection.DeleteOneAsync(
Builders<Holder>.Filter.Eq(e => e.Owner, owner) &
Builders<Holder>.Filter.ElemMatch(e => e.Cards, filter)
);
try {
return res.DeletedCount > 0;
}
catch (Exception ex) {
throw;
}
但这最终只是删除了列表中的所有卡片。 我一直在尝试使用
FindOneAndDeleteAsync
但我无法让它工作。
从您的代码中,您将删除整个
Holder
文档,但不会从 Card
文档中的 Cards
数组中删除 Holder
元素。
我认为 MongoDB .NET 驱动程序不支持删除和返回已删除元素(API)。因此,您应该:
过滤文档并获取过滤后的
Card
元素。
Pull
从 Card
数组中匹配的 Cards
元素。
返回
res.ModifiedCount > 0
表示卡片元素被移除,物品被移除。
var filter = Builders<Card>.Filter.Eq(x => x.Id, cardId);
var holder = await collection.Find(
Builders<Holder>.Filter.Eq(e => e.Owner, owner) &
Builders<Holder>.Filter.ElemMatch(e => e.Cards, filter))
.Project<Holder>(Builders<Holder>.Projection
.Include(x => x.Owner)
.ElemMatch(x => x.Cards, filter))
.FirstOrDefaultAsync();
if (holder == null || !holder.Cards.Any())
{
return new
{
IsCardDeleted = false,
DeletedCards = (List<Card>)null
};
}
UpdateResult res = await collection.UpdateOneAsync(
Builders<Holder>.Filter.Eq(e => e.Owner, owner) &
Builders<Holder>.Filter.ElemMatch(e => e.Cards, filter),
Builders<Holder>.Update.PullFilter(e => e.Cards, filter)
);
if (res.ModifiedCount == 0)
{
return new
{
IsCardDeleted = false,
DeletedCards = (List<Card>)null
};
}
return new
{
IsCardDeleted = true,
DeletedCards = holder.Cards
};