如何匹配 MongoDB 中的子文档数组?

Posted

技术标签:

【中文标题】如何匹配 MongoDB 中的子文档数组?【英文标题】:How do I match an array of sub-documents in MongoDB? 【发布时间】:2019-09-03 06:31:10 【问题描述】:

如果子文档数组中的值大于某个值,则匹配文档,前提是同一文档包含等于某个值的字段

我有一个集合,其中包含带有子文档数组的文档。这个子文档数组包含一个字段,该字段指示我是否可以根据子文档中的另一个字段过滤集合中的文档。当您看到文档示例时,这会更有意义。

      
    "_id":"ObjectId('XXX')",
    "Data":  
        "A":"",
        "B":"-25.78562 ; 28.35629",
        "C":"165"
    ,
    "SubDocuments":[  
          
            "_id":"ObjectId('XXX')",
            "Data":  
                "Value":"XXX",
                "DataFieldId":"B"
            
        ,
          
            "_id":"ObjectId('XXX')",
            "Data":  
                "Value":"",
                "DataFieldId":"A"
            
        ,
          
            "_id":"ObjectId('XXX')",
            "Data":  
                "Value":"105",
                "DataFieldId":"Z"
            
        
    ]

我只想匹配包含具有等于 Z 的 DataFieldId 的子文档的文档,但仅当 Data Field Id 等于 Z 时才过滤大于 105 的值。

【问题讨论】:

你能分享你想要的回应吗? @Jitendra 我正在根据 Data.DataFieldId 和 Data.Value 过滤上面的文档列表。它是聚合管道的一部分... 请确认您希望“DataFieldId”等于“Z”且“Value”大于105。 【参考方案1】:

尝试如下:

db.collection.aggregate([

    $project: 
        _id:1,
        Data:1,
        filteredSubDocuments: 
            $filter: 
                input: "$SubDocuments",
                as: "subDoc",
                cond:  
                    $and: [
                         $eq: ["$$subDoc.Data.DataFieldId", "Z"] ,
                         $gte: ["$$subDoc.Data.Value", 105] 
                    ]
                
            
        
    

])

得到的响应将是:


    "_id" : ObjectId("5cb09659952e3a179190d998"),
    "Data" : 
        "A" : "",
        "B" : "-25.78562 ; 28.35629",
        "C" : "165"
    ,
    "filteredSubDocuments" : [
        
            "_id" : "ObjectId('XXX')",
            "Data" : 
                "Value" : 105,
                "DataFieldId" : "Z"
            
        
    ]

【讨论】:

谢谢@Jitendra。这不是我想要做的。我想根据包含 Data.DataFieldId = "Z" 并且 Data.Value 大于105. 我会尝试阅读更多关于 filter 命令的内容,看看我是否可以让它工作。感谢您的帮助,很抱歉回复晚了。 不客气@FaiyaazKhan。因此,您现在可以从这里了解有关 MongoDB $filter 管道阶段的想法,根据您的要求,您可以在其中应用各种 $and 和 $or 组合以获得所需的结果。【参考方案2】:

这可以通过在子文档上使用$elemMatch 运算符来完成,有关详细信息,您可以单击提供的链接。对于您的问题,您可以使用$elemMatch 尝试以下查询,这比聚合更简单:

    db.collectionName.find(
    "SubDocuments":  
        $elemMatch: 
            "Data.DataFieldId": "Z" , 
            "Data.Value" : $gte: 105  
         
     )

它工作正常,我已经在本地进行了验证,您需要进行的一项修改是您必须根据您的要求将SubDocuments.Data.Value 的值设置为NumberLong

【讨论】:

谢谢@krishna,但这不是我想要做的。我想根据包含 Data.DataFieldId = "Z" 并且 Data.Value 大于105. 我将看看 $elemMatch 命令,看看它是否能够满足我的要求。感谢您的帮助。 不客气,即使您可以尝试聚合管道中的$elemMatch,以供参考检查问题的答案:***.com/questions/47825790/…

以上是关于如何匹配 MongoDB 中的子文档数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Mongo DB 中的子文档数组中删除匹配条件的子文档

如何使用 C# 驱动程序更新 MongoDB 数组中的子文档

如何使用python脚本从mongoDB中检索数组中的子文档

如何使用python脚本从mongoDB中检索数组中的子文档

获取数组中每个索引的子文档元素计数并更新子文档键 - 数组中的子文档(IN MONGODB)

如何使用C#驱动程序更新MongoDB数组中的子文档