MongoDB 使用 C# 驱动程序:如何筛选嵌套对象数组中的字段
MongoDB with C# Driver: How to filter on field within nested array of objects
我是 MongoDB 的新手,一直在努力解决这个问题。假设我有一个包含 ID、名称和对象数组的文档:
{
"_id": {
"$oid": "614ba49b46727413d60b99e2"
},
"Name": 1,
"ObjectArray": [
{
"ObjectId": {
"$oid": "614ba49b46727413d60b99e3"
},
"Value": "some value",
},
{
"ObjectId": {
"$oid": "614ba49b46727413d60b99e5"
},
"Value": "other value",
}
],
}
我有一个映射到此文档的 C# class,在这方面一切正常。假设我只想在新对象的 Id 不存在于数组中时向对象数组添加另一个对象?我正在为此使用 C# 驱动程序并尝试了几种方法。
我尝试了几个想法,包括以下 --
var filter = FilterBuilder.Eq(x => x.Id, id) &
FilterBuilder.Nin(x => x.ObjectArray[-1].ObjectId, new[] { newDoc.ObjectId});
不幸的是,这只检查了对象数组中的第一个对象。因此,如前所述,如果条件全部存在于一个过滤器中,我如何仅向数组添加新对象?
感谢您的宝贵时间。
*** 解决方案 ***
将 Elematch 与 Not 结合使用,将过滤合二为一。
var filter = FilterBuilder.Eq(x => x.Id, id) &
FilterBuilder.Not(FilterBuilder.ElemMatch(x => x.ObjectArray,
Builders<ObjectClass>.Filter.Eq(y => y.ObjectId, newDoc.ObjectId)));
您可以使用 $elemMatch
访问和过滤嵌套的 属性。并将该值与 $eq
.
进行比较
{
"ObjectArray": {
$elemMatch: {
"ObjectId": {
$eq: <value>
}
}
}
}
Complete MongoDB aggregation query
db.collection.aggregate([
{
$match: {
$and: [
{
"_id": {
// With Exist _id
$eq: ObjectId("614ba49b46727413d60b99e2")
}
},
{
"ObjectArray": {
$elemMatch: {
"ObjectId": {
// With unexist ObjectArray.ObjectId
$eq: ObjectId("614ba49b46727413d60b99e3")
}
}
}
}
]
}
}
])
For MongoDB .NET/C# driver
var filter = FilterBuilder.Eq(x => x.Id, id) &
FilterBuilder.ElemMatch(x => x.ObjectArray,
Builders<ObjectClass>.Filter.Eq(y => y.ObjectId, newDoc.ObjectId);
将 ObjectClass
替换为 ObjectArray
中对象的 class 名称。
备注:
使用上述解决方案,当 ObjectArray
中存在已解析的 ObjectId
时,它将 return 文档。因此,您应该 对 已存在的 ObjectId
案例.
进行处理
并且只有在没有查询到文档.
时才将文档添加到ObjectArray
参考资料
我是 MongoDB 的新手,一直在努力解决这个问题。假设我有一个包含 ID、名称和对象数组的文档:
{
"_id": {
"$oid": "614ba49b46727413d60b99e2"
},
"Name": 1,
"ObjectArray": [
{
"ObjectId": {
"$oid": "614ba49b46727413d60b99e3"
},
"Value": "some value",
},
{
"ObjectId": {
"$oid": "614ba49b46727413d60b99e5"
},
"Value": "other value",
}
],
}
我有一个映射到此文档的 C# class,在这方面一切正常。假设我只想在新对象的 Id 不存在于数组中时向对象数组添加另一个对象?我正在为此使用 C# 驱动程序并尝试了几种方法。
我尝试了几个想法,包括以下 --
var filter = FilterBuilder.Eq(x => x.Id, id) &
FilterBuilder.Nin(x => x.ObjectArray[-1].ObjectId, new[] { newDoc.ObjectId});
不幸的是,这只检查了对象数组中的第一个对象。因此,如前所述,如果条件全部存在于一个过滤器中,我如何仅向数组添加新对象?
感谢您的宝贵时间。
*** 解决方案 ***
将 Elematch 与 Not 结合使用,将过滤合二为一。
var filter = FilterBuilder.Eq(x => x.Id, id) &
FilterBuilder.Not(FilterBuilder.ElemMatch(x => x.ObjectArray,
Builders<ObjectClass>.Filter.Eq(y => y.ObjectId, newDoc.ObjectId)));
您可以使用 $elemMatch
访问和过滤嵌套的 属性。并将该值与 $eq
.
{
"ObjectArray": {
$elemMatch: {
"ObjectId": {
$eq: <value>
}
}
}
}
Complete MongoDB aggregation query
db.collection.aggregate([
{
$match: {
$and: [
{
"_id": {
// With Exist _id
$eq: ObjectId("614ba49b46727413d60b99e2")
}
},
{
"ObjectArray": {
$elemMatch: {
"ObjectId": {
// With unexist ObjectArray.ObjectId
$eq: ObjectId("614ba49b46727413d60b99e3")
}
}
}
}
]
}
}
])
For MongoDB .NET/C# driver
var filter = FilterBuilder.Eq(x => x.Id, id) &
FilterBuilder.ElemMatch(x => x.ObjectArray,
Builders<ObjectClass>.Filter.Eq(y => y.ObjectId, newDoc.ObjectId);
将 ObjectClass
替换为 ObjectArray
中对象的 class 名称。
备注:
使用上述解决方案,当 ObjectArray
中存在已解析的 ObjectId
时,它将 return 文档。因此,您应该 对 已存在的 ObjectId
案例.
并且只有在没有查询到文档.
时才将文档添加到ObjectArray