Разница MongoDB между $orderby и Sort

Я хочу получить последний документ, который, очевидно, является единственным документом, поэтому findOne должен работать нормально. Но findOne здесь возвращает первый вставленный документ. Поэтому у меня есть два варианта: либо используйте $orderBy с findOne, либо используйте .sort() функцию с .limit() в find()

Используя $orderBy, он будет выглядеть примерно так:

db.collection.findOne({$query:{},$orderby:{_id:-1}}) 

И используя sort:

db.collection.find().sort({_id:-1}).limit(1).pretty()

Оба работают отлично, я просто хотел узнать, какой запрос я должен здесь использовать? Что касается производительности, либо оба они работают одинаково внутри, и между ними нет такой разницы.

Ответы

Ответ 1

Они одинаковы, и на самом деле страница документации $orderby фактически говорит в основном о функции sort(), которая предоставляется.

Эти модификаторы запросов, которые позволяют добавлять разделы запроса без использования функциональных аксессуаров, существуют, но есть ошибка, смешивающая эти два вместе, поэтому я бы рекомендовал вы выбираете либо модификаторы запросов, либо функциональные методы и придерживаетесь этой опции.

При попытке предоставить примерный код я также обнаружил еще одну вещь, когда снова посмотрел на ваш вопрос. Вы предоставляете:

db.collection.findOne({"$query":{},"$orderby":{ "_id": -1 }}) 

Но хорошо отметить, что:

db.collection.findOne({}).sort({ "_id":-1})

Фактически производит:

2014-07-31T04: 59: 50.183-0700 TypeError: Object [object Object] не имеет метода 'sort'

и, как вы можете видеть здесь, в моем тестовом наборе данных:

> db.rooms.find()
{ "_id" : ObjectId("53ad206e1d8f2d8351182830"), "id" : 1, "from" : ISODate("2014-06-26T00:00:00Z"), "to" : ISODate("2014-06-28T00:00:00Z") }
{ "_id" : ObjectId("53ad276f1d8f2d8351182831"), "id" : 1, "from" : ISODate("2014-06-24T00:00:00Z"), "to" : ISODate("2014-07-01T00:00:00Z") }
{ "_id" : ObjectId("53ad28ad1d8f2d8351182832"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-06-28T00:00:00Z") }
{ "_id" : ObjectId("53ad28c61d8f2d8351182833"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-07-03T00:00:00Z") }
{ "_id" : ObjectId("53ad29971d8f2d8351182834"), "id" : 1, "from" : ISODate("2014-06-20T00:00:00Z"), "to" : ISODate("2014-06-21T00:00:00Z") }

ответ на самом деле правильный:

> db.rooms.findOne({ "$query":{}, "$orderby":{ "_id": -1 }})
{
        "_id" : ObjectId("53ad29971d8f2d8351182834"),
        "id" : 1,
        "from" : ISODate("2014-06-20T00:00:00Z"),
        "to" : ISODate("2014-06-21T00:00:00Z")
}

Поэтому интересно отметить, что модификаторы запросов поддерживаются findOne, где в качестве функциональных аксессуаров нет, что может быть причиной использования модификаторов запросов.

Ответ 2

По состоянию на Mongo 3.2, $orderby устарел.

docs явно говорят:

Оператор $orderby устарел. Вместо этого используйте cursor.sort().

К сожалению, findOne() не поддерживает метод sort(), поэтому вам нужно переключиться на find():

db.collection.find({}).sort({'key': -1}).limit(1)

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