MongoDB 获取子文档

问题描述 投票:0回答:3

我想从 MongoDB 中的文档中检索子文档。我有以下文件:

{
    "_id" : "10000",
    "password" : "password1",
    "name" : "customer1",
    "enabled" : true,
    "channels" : [ 
        {
            "id" : "10000-1",
            "name" : "cust1chan1",
            "enabled" : true
        }, 
        {
            "id" : "10000-2",
            "name" : "cust1chan2",
            "enabled" : true
        }
    ]
}

我想要的结果是:

{
    "id" : "10000-1",
    "name" : "cust1chan1",
    "enabled" : true
}

但是,到目前为止我能做的最好的就是使用以下查询:

db.customer.find({"channels.id" : "10000-1"}, {"channels.$" : 1, "_id" : 0})

但这给了我以下结果:

{
    "channels" : [ 
        {
            "id" : "10000-1",
            "name" : "cust1chan1",
            "enabled" : true
        }
    ]
}

有谁知道是否可以编写一个查询来给我想要的结果?任何帮助将不胜感激。

mongodb mongodb-query aggregation-framework
3个回答
14
投票

你可以用聚合框架来做。查询将类似于:

db.customer.aggregate([
    {$unwind : "$channels"},
    {$match : {"channels.id" : "10000-1"}},
    {$project : {_id : 0, 
                 id : "$channels.id", 
                 name : "$channels.name", 
                 enabled : "$channels.enabled"}}
])

3
投票

使用 MongoDB 3.4.4 及更新版本,聚合框架提供了许多可用于返回所需子文档的运算符。

考虑运行一个聚合管道,该管道使用单个

$replaceRoot
阶段将过滤后的子文档提升到顶层并替换所有其他字段。

过滤子文档需要

$filter
运算符,它根据指定的条件选择要返回的数组的子集,即返回仅包含与条件匹配的元素的数组。然后,您可以使用
$arrayElemAt
运算符将单个数组元素转换为文档

总的来说,运行这个聚合操作会产生预期的结果:

db.customer.aggregate([
    { "$replaceRoot": { 
        "newRoot": {
            "$arrayElemAt": [
                { "$filter": {
                   "input": "$channels",
                   "as": "channel",
                   "cond": { /* resolve to a boolean value and determine if an element should be included in the output array. */
                       "$eq": ["$$channel.id", "10000-1"]
                    } 
                } },
                0 /* the element at the specified array index */
            ]
        }
    } }
])

输出

{
    "id" : "10000-1",
    "name" : "cust1chan1",
    "enabled" : true
}

0
投票

我知道可能有点晚了,但我遇到了类似的情况,我想出了解决方案。在聚合管道中,您可以先通过匹配子文档过滤掉数据,然后展开嵌套数组字段,然后替换根。

db.customer.aggregate([
    [
        { $match: { "channels.id": "10000-1" }},
        { $unwind: "$channels" },
        { $replaceRoot: { newRoot: "$channels" } }
    ]
])
© www.soinside.com 2019 - 2024. All rights reserved.