【问题标题】:Use MongoDB $slice operator on an array within an array在数组中的数组上使用 MongoDB $slice 运算符
【发布时间】:2015-11-10 10:12:57
【问题描述】:

我有一个如下所示的架构:

> 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”:[ ... 返回整个对象 ... }

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

【问题讨论】:

  • 你的预期输出是什么?
  • 对不起,我应该提到,对于我的错误查询:db.test.findOne({}, {"l0.0.l1" : {$slice: 2}}) 它应该是:{ "_id" : "1:1419552000", "l0" : [ "2", "1" ] } 或类似

标签: arrays mongodb mongodb-query slice


【解决方案1】:

您可以使用带有$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】:

    您没有在问题中指定所需的输出。假设您只想返回满足特定范围条件(例如 >41)的 l1 元素,您可以使用 $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"]
    }
    

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

    【讨论】:

    • 感谢您的回复!很抱歉没有在问题中添加预期的输出。现在将其添加为评论。接受另一个答案,IMO,更好地解释了事情。再次感谢。
    【解决方案3】:

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

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

    【讨论】:

    • 感谢您的回复,这不是我的想法。我刚刚用 cmets 中的预期输出更新了问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-09
    • 2020-06-16
    • 2021-12-25
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    相关资源
    最近更新 更多