选择一个子文档数组,并在每个子文档中包含父项的字段

时间:2017-10-27 20:43:19

标签: mongodb mongodb-query

假设我有这样的文件:

public static Task LoadPageAsync(this IWebBrowser browser, string address = null)
{
    var tcs = new TaskCompletionSource<bool>();

    EventHandler<LoadingStateChangedEventArgs> handler = null;
    handler = (sender, args) =>
    {
        //Wait for while page to finish loading not just the first frame
        if (!args.IsLoading)
        {
            browser.LoadingStateChanged -= handler;
            tcs.TrySetResult(true);
        }
    };

    browser.LoadingStateChanged += handler;

    if (!string.IsNullOrEmpty(address))
    {
        browser.Load(address);
    }
    return tcs.Task;
}

我想查询此文档,以便得到如下结果:

{
    _id: "a",
    title: "Hello",
    info: [
       {
           _id: "a1",
           item: "b"
       },
       {
           _id: "a2",
           item: "c"
       },
    ]
}

如果我只想获得这些项目中的一项,请说明项目

_id: "a1"
我可以进行查询,例如

[
    {
        title: "Hello",
        _id: "a1",
        item: "b"
    },
    {
        title: "Hello",
        _id: "a2",
        item: "c"
    }
]

我将获得单个子文档的正确结果。我的问题是如何将其扩展为每个项目?

提前致谢。

2 个答案:

答案 0 :(得分:1)

您可以使用聚合框架的 $ unwind 运算符将具有嵌套数组的一个元素转换为具有嵌套信息字段的两个文档。然后你可以使用 $ project 来摆脱嵌套。在最后阶段,您可以使用 $ match 过滤新表单。

db.yourCollection.aggregate([
   { $unwind: "$info" },
   { $project: { title: 1, _id: "$info._id", item: "$info.item"} },
   { $match: {_id: "a1"}}
])

此类查询将返回如下文档:

{ "title" : "Hello", "_id" : "a1", "item" : "b" }

答案 1 :(得分:0)

MongoDB聚合操作有助于使用$unwind$match聚合阶段的组合将过滤器应用于嵌入式文档。

根据上述问题的描述,请尝试在MongoDB shell中执行以下聚合查询。

db.myCollection.aggregate(

    // Pipeline
    [
        // Stage 1
        {
            $match: {
                "_id": "a"
            }
        },

        // Stage 2
        {
            $unwind: {
                path: "$info",

                preserveNullAndEmptyArrays: true
            }
        },

        // Stage 3
        {
            $match: {
                'info._id': 'a1'
            }
        },

        // Stage 4
        {
            $project: {
                title: 1,
                _id: '$info._id',
                item: '$info.item'
            }
        },

    ]



);