Цепная сортировка и ограничение по времени - PullRequest
2 голосов
/ 12 декабря 2011

В последнее время я сталкивался с некоторыми странными поведениями (то есть подразумевал, что они, ИМХО, нелогичны) при игре с монго и сортировкой / лимитом.

Предположим, у меня есть следующая коллекция:

> db.fred.find()
{ "_id" : ObjectId("..."), "record" : 1, "time" : ISODate("2011-12-01T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 2, "time" : ISODate("2011-12-02T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 3, "time" : ISODate("2011-12-03T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 4, "time" : ISODate("2011-12-04T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 5, "time" : ISODate("2011-12-05T00:00:00Z") }

Я хотел бы получить по порядку времени 2 записи, предшествующие «записи»: 4 плюс запись 4 (т.е. запись 2, запись 3 и запись 4)

Наивно ябыло что-то вроде:

db.fred.find({time: {$lte: ISODate("2011-12-04T00:00:00Z")}}).sort({time: -1}).limit(2).sort({time: 1})

, но это не сработало так, как я ожидал:

{ "_id" : ObjectId("..."), "record" : 1, "time" : ISODate("2011-12-01T00:00:00Z") }
{ "_id" : ObjectId("..."), "record" : 2, "time" : ISODate("2011-12-02T00:00:00Z") }

Я думал, что результатом будут записи 2, 3 и 4.

Из того, что я вспомнил, кажется, что сортировка 2 применяется до лимита:

  sort({time: -1})                          => record 4, record 3, record 2, record 1
  sort({time: -1}).limit(2)                 => record 4, record 3
  sort({time: -1}).limit(2).sort({time: 1}) => record 1, record 2

т.е. как будто вторая сортировка была применена к курсору, возвращенному функцией find (т.е.установить) и только затем применяется ограничение.

В чем здесь моя ошибка и как мне добиться ожидаемого поведения?

Кстати: запуск mongo 2.0.1 в Ubuntu 11.01

Ответы [ 2 ]

3 голосов
/ 12 декабря 2011

Применение sort() к одному и тому же запросу несколько раз не имеет смысла.Эффективная сортировка будет взята из последнего sort() вызова.Таким образом,

sort({time: -1}).limit(2).sort({time: 1})

совпадает с

sort({time: 1}).limit(2)
3 голосов
/ 12 декабря 2011

Оболочка MongoDB лениво оценивает курсоры, то есть, последовательность выполненных вами цепочек операций приводит к тому, что один запрос отправляется на сервер с использованием конечного состояния на основе цепочечных операций. Поэтому, когда вы говорите «sort({time: -1}).limit(2).sort({time: 1})», второй вызов sort переопределяет сортировку, установленную первым вызовом.

Чтобы достичь желаемого результата, вам, вероятно, лучше поменять вывод курсора в коде приложения, особенно если вы ограничиваетесь небольшим набором результатов (здесь вы используете 2). Точный код для этого зависит от языка, который вы используете, который вы не указали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...