Mongodb:按数组对象对文档进行排序

时间:2011-03-15 17:33:57

标签: mongodb database nosql

我想按顺序返回文档,其中包含最低foo.bar值(数组对象)。

我可以db.collection.find().sort({foo.0.bar: 1}),但这只匹配数组中的第一个元素 - 正如您在下面的示例中所看到的那样,首先对项目1进行排序(foo.0.bar = 5),我是希望首先返回第2项(foo.2.bar = 4),因为它具有最低值的对象。

{
    "name": "Item 1",
    "foo": [
        {
            "bar": 5
        },
        {
            "bar": 6
        },
        {
            "bar": 7
        }
    ]
}
{
    "name": "item 2",
    "foo": [
        {
            "bar": 6
        },
        {
            "bar": 5
        },
        {
            "bar": 4
        }
    ]
}

4 个答案:

答案 0 :(得分:19)

似乎mongo 可以这样做。

例如,如果我有以下文件:

{ a:{ b:[ {c:1}, {c:5 } ] } }
{ a:{ b:[ {c:0}, {c:12} ] } }
{ a:{ b:[ {c:4}, {c:3 } ] } }
{ a:{ b:[ {c:1}, {c:9 } ] } }

并执行以下操作:

db.collection.find({}).sort({ "a.b.c":1 });
// produces:
{ a:{ b:[ {c:0}, {c:12} ] } }
{ a:{ b:[ {c:1}, {c:5 } ] } }
{ a:{ b:[ {c:1}, {c:9 } ] } }
{ a:{ b:[ {c:4}, {c:3 } ] } }

db.collection.find({}).sort({ "a.b.c":-1 });
// produces:
{ a:{ b:[ {c:0}, {c:12} ] } }
{ a:{ b:[ {c:1}, {c:9 } ] } }
{ a:{ b:[ {c:1}, {c:5 } ] } }
{ a:{ b:[ {c:4}, {c:3 } ] } }

正如您所看到的,{"a.b.c":1}排序采用数组中所有值的 min 并对其进行排序,而按{"a.b.c":-1}排序则采用最大所有值。

答案 1 :(得分:4)

使用map / reduce的另一种方法是将数组中的min值作为文档中的单独字段存储,然后您可以在其中进行排序。添加到数组时,如果新值低于当前记录的最小值,则还会更新此字段。

e.g。你的第一个文件将成为这个(注意“minbar added”):

{
    "name": "Item 1",
    "minbar" : 5,
    "foo": [
        {
            "bar": 5,
        }
        {
            "bar": 6,
        }
        {
            "bar": 7,
        }
    ]
}

答案 2 :(得分:4)

你可以使用mongo 2.2版的聚合命令进行这样的排序:

    db.collection.aggregate([{$unwind: "$foo"},
    {$project: {bars:"$foo.bar"}},
    {$group: {_id:"$_id",min:{$min: "$bars"}}},
    {$sort: {min:1}}])

答案 3 :(得分:0)

在mongo中没有直接的方法。您需要使用map / reduce来检索每个数组中的最小值,然后按该最小值进行排序