带有 C#Driver 的 MongoDB:如何过滤嵌套对象数组中的字段

Posted

技术标签:

【中文标题】带有 C#Driver 的 MongoDB:如何过滤嵌套对象数组中的字段【英文标题】:MongoDB with C#Driver: How to filter on field within nested array of Objects 【发布时间】:2021-11-18 00:05:55 【问题描述】:

我是 MongoDB 新手,一直在努力解决这个问题。假设我有一个包含 id、名称和对象数组的文档:


    "_id": 
        "$oid": "614ba49b46727413d60b99e2"
    ,
    "Name": 1,
    "ObjectArray": [
    
        "ObjectId": 
            "$oid": "614ba49b46727413d60b99e3"
        ,
        "Value": "some value", 
    , 
    
        "ObjectId": 
            "$oid": "614ba49b46727413d60b99e5"
        ,
        "Value": "other value",
    
    ],

我有一个映射到该文档的 C# 类,并且在这方面一切正常。假设我只想在数组中不存在新对象的 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)));

【问题讨论】:

【参考方案1】:

您可以使用$elemMatch 访问和过滤嵌套属性。并将该值与$eq 进行比较。


  "ObjectArray": 
    $elemMatch: 
      "ObjectId": 
        $eq: <value>
      
    
  

完成 MongoDB 聚合查询

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

对于 MongoDB .NET/C# 驱动程序

var filter = FilterBuilder.Eq(x => x.Id, id) & 
             FilterBuilder.ElemMatch(x => x.ObjectArray, 
                 Builders<ObjectClass>.Filter.Eq(y => y.ObjectId, newDoc.ObjectId);

ObjectClass 替换为ObjectArray 中对象的类名。

备注

通过上述解决方案,当解析的ObjectId 存在于ObjectArray 中时,它将返回该文档。因此,您应该对现有的ObjectId 案例进行处理

并且仅在没有查询到文档时才将文档添加到ObjectArray


参考文献

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

【讨论】:

终于让它与 c# 驱动程序的 elematch 一起使用。必须将 Not 函数与 elematch 结合使用。谢谢你的回答。

以上是关于带有 C#Driver 的 MongoDB:如何过滤嵌套对象数组中的字段的主要内容,如果未能解决你的问题,请参考以下文章

使用 MongoDB Driver for C# 的不同查询比通过 MongoDB shell 发送的相同查询慢得多

c#mongodb.driver 连接模式都有哪些

如何使`org.mongodb.driver.cluster`在spring boot中使用嵌入式mongodb?

MongoDB Native Node.js Driver

C# .Net + MongoDB Atlas 连接字符串 MongoDB.Driver.Legacy 尝试运行客户端时出错

Mongodb.Driver操作MongoDB