Mongo按数组长度排序

时间:2012-01-27 21:13:28

标签: mongodb size sql-order-by

假设我有像这样的mongo文件:

问题1

{
    answers:[
       {content: 'answer1'},
       {content: '2nd answer'}
    ]
}

问题2

{
    answers:[
       {content: 'answer1'},
       {content: '2nd answer'}
       {content: 'The third answer'}
    ]
}

有没有办法按答案大小订购收藏品?

经过一番研究后,我看到了添加另一个字段的建议,其中包含了许多答案并将其用作参考,但可能有本地方法可以做到吗?

4 个答案:

答案 0 :(得分:45)

我认为你可以使用$size,但这只是为了找到一定大小的数组而不是排序。

来自mongo文档: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size

  

您不能使用$ size来查找一系列大小(例如:具有多于1个元素的数组)。如果需要查询范围,请创建一个额外的大小字段,在添加元素时递增。索引不能用于查询的$ size部分,但如果包含其他查询表达式,索引可用于搜索查询表达式的该部分的匹配项。

看起来您可以使用新的聚合框架编辑来完成此操作,但尚未推出。 http://www.mongodb.org/display/DOCS/Aggregation+Framework

更新现在聚合框架已经结束......

> db.test.aggregate([
  {$unwind: "$answers"}, 
  {$group: {_id:"$_id", answers: {$push:"$answers"}, size: {$sum:1}}}, 
  {$sort:{size:1}}]);
{
"result" : [
    {
        "_id" : ObjectId("5053b4547d820880c3469365"),
        "answers" : [
            {
                "content" : "answer1"
            },
            {
                "content" : "2nd answer"
            }
        ],
        "size" : 2
    },
    {
        "_id" : ObjectId("5053b46d7d820880c3469366"),
        "answers" : [
            {
                "content" : "answer1"
            },
            {
                "content" : "2nd answer"
            },
            {
                "content" : "The third answer"
            }
        ],
        "size" : 3
    }
  ],
  "ok" : 1
}

答案 1 :(得分:33)

我正在使用$ project:

db.test.aggregate([
    {
        $project : { answers_count: {$size: { "$ifNull": [ "$answers", [] ] } } }
    }, 
    {   
        $sort: {"answers_count":1} 
    }
    ])

它还允许包含空答案的文档。 但也有缺点(或有时候有优势):你应该在项目步骤中手动添加所有需要的字段。

答案 2 :(得分:2)

您可以使用mongodb聚合阶段$addFields,它将添加额外的字段来存储计数,然后是$sort阶段。

db.test.aggregate([
    {
        $addFields: { answers_count: {$size: { "$ifNull": [ "$answers", [] ] } } }
    }, 
    {   
        $sort: {"answers_count":1} 
    }
])

答案 3 :(得分:1)

您可以使用 $size 属性按数组长度排序。

db.getCollection('test').aggregate([
{$project: { "answers": 1, "answer_count": { $size: "$answers" } }},
{$sort: {"answer_count": -1}}])