【问题标题】:How do I match an array of sub-documents in MongoDB?如何匹配 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。

标签: mongodb mongodb-query


【解决方案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,以供参考检查问题的答案:stackoverflow.com/questions/47825790/…
猜你喜欢
  • 2019-07-09
  • 2021-05-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多