Монго порядок по длине массива - PullRequest
39 голосов
/ 28 января 2012

Допустим, у меня есть такие документы на монго:

Вопрос 1

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

Вопрос 2

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

Есть ли способ заказать сборник по размеру ответов?

После небольшого исследования я увидел предложения о добавлении еще одного поля, которое будет содержать количество ответов и использовать его в качестве справочного материала, но, возможно, есть собственный способ сделать это?

Ответы [ 3 ]

47 голосов
/ 28 января 2012

Я думал, что вы могли бы использовать $size, но это только для поиска массивов определенного размера, а не порядка.

Из документации Монго: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size

Вы не можете использовать $ size, чтобы найти диапазон размеров (например: массивы с более чем 1 элементом).Если вам нужно запросить диапазон, создайте поле дополнительного размера, которое вы увеличиваете при добавлении элементов.Индексы нельзя использовать для части запроса в размере $ size, хотя, если включены другие выражения запроса, индексы могут использоваться для поиска совпадений в этой части выражения запроса.довольно легко сделать это с новой структурой агрегации, edit: , которая еще не выпущена.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
}
33 голосов
/ 12 января 2015

Я использую $ project для этого:

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

Позволяет также включать документы с пустыми ответами.Но также имеет недостаток (или иногда преимущество): вы должны вручную добавить все необходимые поля в шаге проекта.

2 голосов
/ 05 февраля 2019

вы можете использовать этап агрегации mongodb $addFields, который добавит дополнительное поле для хранения счетчика, а затем последует этап $sort.

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