Я работаю над проектом, и я не уверен, есть ли разница между тем, как findработает курсор и как findOneработает курсор. FindOne - просто обертка для find().limit(1)? Я искал это и, возможно, кто-то знает, есть ли у mongodb специальный метод для этого или нет. Я работаю с PHP API для mongodb, если это имеет значение.
Исходя из моих собственных тестов, find().limit(1)это на порядки быстрее, чем findOne().
Существует либо ошибка в документации MongoDB, либо ошибка в findOne(). findOne()больше похоже на то, find().limit(N)где N - количество документов, которое должен вернуть запрос. Я понял это, пытаясь понять, почему мои простые запросы были такими медленными!
обновление: ответ от инженера 10gen (MongoDB):
Два запроса, которые вы выполняете, очень разные. Запрос на поиск возвращает курсор, это по сути сценарий без операций, так как никакие фактические данные не возвращаются (только информация о курсоре). Если вы вызываете findOne, то вы фактически возвращаете данные и закрываете курсор. Документы определенно должны быть понятнее :-)
Обновление: действительно, если find().limit(1)документ извлекается, разница в скорости на порядки кажется исчезающей. Кроме того, я не смог воспроизвести существенную разницу в скорости с драйвером MongoDB JavaScript. Первоначально я тестировал с помощью драйвера MongoDB Java.
Отличная находка. Важный вопрос, однако: учитывают ли ваши тесты дополнительные операции, с которыми вам придется иметь дело find().limit(1)в ходе обычного программирования (например, на самом деле извлечение данных и закрытие курсора), которое findOne()в любом случае автоматически делает для вас?
Ник Чаммас
@ Ник: Я думаю, что дополнительные операции были покрыты. Я находил случайный документ ( cookbook.mongodb.org/patterns/random-attribute ), получал документ с помощью .next () и удалял его из коллекции. Я не закрывал вручную никаких курсоров ...
Leftium
@Leftium, тогда я должен спросить, быстрее ли сделать find.limit (1) и затем получить значение cursur, или быстрее найти findone ()
WojonsTech
2
@WojonsTech: быстрый тест в JS показывает, что findOne () на самом деле быстрее. Результаты могут отличаться в зависимости от водителя / платформы. Например, я не смог воспроизвести разницу скорости порядка в JS, которую я первоначально наблюдал с драйвером Java.
Leftium
2
Leftium, я бы отредактировал ваш ответ, подчеркнув, что когда вы на самом деле получаете документ (что вы обычно делаете), две функции фактически идентичны, как указано в документации. Прямо сейчас кто-то, скорее всего, прочтет жирную строку в начале вашего ответа и решит, что если он хочет получить один документ, findOne()это хуже, чем find().limit(1)неверно.
Ник Чаммас
5
findOne()действительно синтаксический сахар для find().limit(1), учитывая, что вы на самом деле извлекаете документ (в отличие от простого возврата курсора с помощью find()).
Смотрите ответ и обновления Leftium для более подробной информации.
хорошо, спасибо, я не люблю использовать в своем программировании функции synimus, я бы предпочел сам ограничить их, чтобы весь мой код легко отслеживать.
WojonsTech
1
На самом деле в тестах findOne () немного быстрее, чем find (). Limit (1).
Владимир
@ DairT'arg - Если у вас есть источники или данные, подтверждающие эту претензию, обязательно опубликуйте ответ с подробностями! Из того, что я до сих пор собирал, они должны быть идентичными, если вы извлекаете документ в обоих случаях.
Ник Чаммас
3
Исходный код может сильно помочь.
Это Java, но я думаю, это тоже может помочь.
findOne(),
DBObject findOne(DBObject o, DBObject fields, DBObject orderBy, ReadPreference readPref,
long maxTime, TimeUnit maxTimeUnit){
QueryOpBuilder queryOpBuilder = new QueryOpBuilder().addQuery(o).addOrderBy(orderBy).addMaxTimeMS(MILLISECONDS.convert(maxTime, maxTimeUnit));if(getDB().getMongo().isMongosConnection()){
queryOpBuilder.addReadPreference(readPref);}
Iterator<DBObject> i = find(queryOpBuilder.get(), fields,0,-1,0, getOptions(), readPref, getDecoder());
DBObject obj =(i.hasNext()? i.next():null);if( obj !=null&&( fields !=null&& fields.keySet().size()>0)){
obj.markAsPartialObject();}return obj;}
И вот find()
public DBCursor find( DBObject ref ){return new DBCursor( this, ref,null, getReadPreference());}
Как мы можем видеть , что findOne()вызовы find()в нем себя, получает все DBOjectв iи затем возвращают первый.
find().limit(1)
в ходе обычного программирования (например, на самом деле извлечение данных и закрытие курсора), котороеfindOne()
в любом случае автоматически делает для вас?findOne()
это хуже, чемfind().limit(1)
неверно.findOne()
действительно синтаксический сахар дляfind().limit(1)
, учитывая, что вы на самом деле извлекаете документ (в отличие от простого возврата курсора с помощьюfind()
).Смотрите ответ и обновления Leftium для более подробной информации.
источник
Исходный код может сильно помочь.
Это Java, но я думаю, это тоже может помочь.
findOne()
,И вот
find()
Как мы можем видеть , что
findOne()
вызовыfind()
в нем себя, получает всеDBOject
вi
и затем возвращают первый.источник
Вы должны проверить эту ссылку ...
http://mongoosejs.com/docs/2.7.x/docs/finding-documents.html
источник