MongoDB多维数组投影

时间:2015-10-09 09:21:14

标签: mongodb multidimensional-array aggregation-framework

我刚开始学习MongoDB,无法找到解决问题的方法。

得到那份文件:

> db.test.insert({"name" : "Anika", "arr" : [ [11, 22],[33,44] ] })

请注意“arr”字段,它是一个多维数组。

现在我正在寻找一个只返回arr [0] [1]值22的查询。我试图通过使用$ slice来实现它,但是我不知道如何解决第二个维度那个。

> db.test.find({},{_id:0,"arr":{$slice: [0,1]}})
{ "name" : "ha", "arr" : [ [ 11, 22 ] ] }

我也试过

> db.test.find({},{_id:0,"arr":{$slice: [0,1][1,1]}})
{ "name" : "ha", "arr" : [ [ 11, 22 ] ] }

所需的输出是

22

{"arr":[[22]]}

谢谢

修改

阅读评论后,我认为我已经过多地简化了示例数据,我必须提供更多信息:

  1. 该集合中有更多文档,就像那个 我提供了。但它们都具有相同的结构。
  2. 阵列元素多于两个
  3. 在现实世界中,数组包含非常长的文本(500kb-1mb), 因此将整个数据传输到客户端非常容易。
  4. 在聚合之前,我将通过'name'字段进行查询。只是 为了简单起见,在示例中跳过了它。
  5. 目标索引是可变的,所以有时我需要知道 arr [0] [1]的值,下次是arr [1] [4]
  6. 示例数据:

    > db.test.insert({"name" : "Olivia", "arr" : [ [11, 22, 33, 44],[55,66,77,88],[99] ] })
    > db.test.insert({"name" : "Walter", "arr" : [ [11], [22, 33, 44],[55,66,77,88],[99] ] })
    > db.test.insert({"name" : "Astrid", "arr" : [ [11, 22, 33, 44],[55,66],[77,88],[99] ] })
    > db.test.insert({"name" : "Peter",  "arr" : [ [11, 22, 33, 44],[55,66,77,88],[99] ] })
    

    示例查询:

    > db.test.find({name:"Olivia"},{"arr:"...})
    

2 个答案:

答案 0 :(得分:2)

您可以使用聚合框架:

db.test.aggregate([
    { $unwind: '$arr' },
    { $limit: 1 },
    { $project: { _id: 0, arr: 1 } },
    { $unwind: '$arr' },
    { $skip: 1 },
    { $limit: 1 }
])

返回:

{ "arr": 22 }

修改:原始海报修改了我的解决方案以满足他的需求,并提出了以下建议:

db.test.aggregate([
    { $match: { name:"Olivia" } },
    { $project: { _id: 0,arr: 1 } },
    { $unwind: '$arr' },
    { $skip: 1 },
    { $limit:1 },
    { $unwind: "$arr" },
    { $skip: 2 },
    { $limit: 1 }
])

此查询将导致{ arr: 77 }给出OP提供的扩展数据。请注意,需要$ skip和$ limit来选择数组层次结构中的正确元素。

答案 1 :(得分:0)

您要求的$slice表单不会执行多维数组。每个数组都是单独考虑的,因此当前$slice不支持这种方式。

因此,它实际上在索引上完成了很短的时间"首先"和"最后"使用.aggregate()建议的值,目前:

db.test.aggregate([
    { "$unwind": "$arr" },
    { "$group": {
        "_id": "$_id",
        "arr": { "$first": "$arr" }
    }},
    { "$unwind": "$arr" },
    { "$group": {
        "_id": "$_id",
        "arr": { "$last": "$arr" }
    }}
])

但是在未来的MongoDB版本中(目前在开发分支3.18中起作用),你有$arrayElemAt作为聚合框架的运算符,其工作方式如下:

db.test.aggregate([
    { "$project": {
        "arr": {
            "$arrayElemAt": [
                { "$arrayElemAt": [ "$arr", 0 ] },
                1
            ]
        }
    }}
])

两者基本上都得到了相同的{ "arr": 22 }结果,尽管未来可用的表单在数组索引值上非常灵活,而不是第一个和最后一个。