2013-07-09 3 views
0

У меня есть коллекция Монго с документами, как-Монго сортировать по нескольким полям в вложенном массиве

{ 
_id : 1abc, 
'data' :'blah', 
'createdDate' : ISODate("2013-05-26T01:34:10Z"), 
'a': [ 
    { 
     _id : a1adas, 
     'createdDate' : ISODate("2013-05-26T01:35:10Z"), 
     'b':[ 
       { 
        _id : aadaasd 
        'createdDate' : ISODate("2013-05-26T01:37:10Z"), 
       } 
      ] 
    } 
] 

}

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

До сих пор у меня есть этот запрос, который я не уверен, работает как ожидалось.

db.collection.find({'data':'blah'}).sort({'createdDate':-1, 'a.createdDate': -1, 'a.b.createdDate': -1 }).explain(); 

Я хотел бы знать, есть ли более эффективный способ выполнения такого рода.

ответ

2

Ваш запрос не делает то, что вы хотели бы сделать. Сортировка MongoDB по нескольким полям будет обрабатывать каждое поле по очереди, а не все три поля вместе. Например, я вставил несколько тестовых документов в коллекции, и я запустить подобного рода:

> db.numbers.find().sort({ a : -1, b : -1, c : -1 }) 
{ doc : "doc1", "a" : 13, "b" : 5, "c" : 7 } 
{ doc : "doc2", "a" : 12, "b" : 20, "c" : 91 } 
{ doc: "doc3", "a" : 2, "b" : 50, "c" : 700 } 

«doc3» имеет самое низкое значение а, так как он будет возвращен в последний раз. Тем не менее, он также имеет самое высокое значение любого поля в сортировке, поэтому теоретически мы хотели бы, чтобы это было первым, что вернулось. Мы можем сделать это с помощью MongoDB-х aggregation framework:

db.numbers.aggregate(
{ $project : { 
    _id : 1, 
    a : 1, 
    maxNum : { $cond: [{ $gte : [ "$b", "$c" ]}, "$b" , "$c" ]} // max of b, c 
    }}, 
{ $project : { 
    _id : 1, 
    maxNum : { $cond: [{ $gte : [ "$a", "$maxNum" ]}, "$a" , "$maxNum" ]} // max of a, b, c 
    }}, 
{ $sort : { maxNum : -1 } } 
) 

Это объединение запросов преобразует данные в форму, где Ваш вид может быть правильно выполнена. Однако, это не легко понять, как это происходит. В настоящее время для запросов агрегирования нет .explain().

Смежные вопросы