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")
              }
            }
          }
        }
      ]
    }
  }
])

Sample Mongo Playground

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

参考资料

  1. $elemMatch
  2. Similar scenario for filtering a document in an array with MongoDB .NET/C# driver