在数组中的数组上使用MongoDB $ slice运算符

时间:2015-11-10 10:12:57

标签: arrays mongodb mongodb-query slice

我的架构看起来像这样:

> db.test.findOne()
{
    "_id" : "1:1419552000",
    "l0" : [
        {
            "l1" : [
                "1",
                "2",
                "3",
                "4"
            ]
        },
        {
            "l1" : [
                "11",
                "12",
                "13",
                "14"
            ]
        },
        {
            "l1" : [
                "21",
                "22",
                "23",
                "24"
            ]
        },
        {
            "l1" : [
                "31",
                "32",
                "33",
                "34"
            ]
        },
        {
            "l1" : [
                "41",
                "42",
                "43",
                "44"
            ]
        }
    ]
}

我希望能够从级别1(l1)的任何数组中获取一系列元素。但$ slice运算符并不能做到这一点。这根本不可能吗?

> db.test.findOne({}, {"l0" : {$slice: 1}})
{
    "_id" : "1:1419552000",
    "l0" : [
        {
            "l1" : [
                "1",
                "2",
                "3",
                "4"
            ]
        }
    ]
}

> db.test.findOne({}, {"l0.0.l1" : {$slice: 2}})
{
    "_id" : "1:1419552000",
    "l0" : [
...
returns the entire object
...
}

欢迎任何指示或帮助。谢谢!

3 个答案:

答案 0 :(得分:2)

您没有在问题中指定所需的输出。假设您只想返回符合特定范围标准的l1元素(例如> 41),您可以使用$unwind参数和aggregate函数:

 db.test.aggregate({
    $unwind: "$l0"
}, {
    $unwind: "$l0.l1"
}, {
    $match: {
        "l0.l1": {
            $gt: "41"
        }
    }
}, {
    "$group": {
        "_id": "$_id",
        "l1": {
            "$addToSet": "$l0.l1"
        }
    }
})

这将返回:

{
   "_id": "1:1419552000",
    "l1": ["43", "44", "42"]
}

如果您在问题中添加了所需的输出,我可以修改查询以返回正确的输出。

答案 1 :(得分:2)

您可以将聚合框架与$skip$limit$unwind结合使用,以达到所需的子阵列范围:

db.test.aggregate(
    {
        $match: { _id: "1:1419552000" }
    },
    {
        $unwind: "$l0"
    },
    {
        $limit: 1 // keeps the first element in l0
    },
    {
        $unwind: "$l0.l1"
    },
    {
        $limit: 2 // keeps the first two elements in the first l1
    },
    {
        $group: // groups the unwound elements back into an array
        {
            _id: "$_id",
            l0: { $addToSet: "$l0.l1" }
        }
    }
)

将返回:

{ "_id" : "1:1419552000", "l0" : [ "2", "1" ] }

答案 2 :(得分:-1)

对于您提供的示例文档,db.test.findOne({}, {"l0.l1" : {$slice: 2}})返回

{
    "_id" : "1:1419552000",
    "l0" : [
        {
            "l1" : [
                "1",
                "2"
            ]
        },
        {
            "l1" : [
                "11",
                "12"
            ]
        }, ...