Pracuji na projektu a nejsem si jistý, zda existuje rozdíl mezi tím, jak funguje kurzor find
a způsobem, jakým funguje kurzor findOne
. Je findOne pouze wrapper pro find().limit(1)
? Hledal jsem to a možná někdo ví, jestli mongodb má speciální metodu nebo ne. Pracuji s API PHP API pro mongodb), pokud to dělá rozdíl.
Na základě mých vlastních měřítek je find().limit(1)
je řádová velikost rychlejší než findOne()
.
V dokumentaci MongoDB je chyba nebo chyba v findOne()
. findOne()
provádí více jako find().limit(N)
kde N je počet dokumentů, které by dotaz vrátil. Přišel jsem na to a snažil jsem se přijít na to, proč byly moje jednoduché dotazy tak pomalé!
pdate: odpověď od inženýra 10gen (MongoDB):
Dva dotazy, které provádíte, se velmi liší. Vyhledávací dotaz vrátí kurzor, což je v podstatě scénář bez operace, protože se nevracejí žádná skutečná data (pouze informace o kurzoru). Pokud voláte findOne, pak vracíte data a uzavíráte kurzor. Dokumenty by rozhodně měly být jasnější :-)
Aktualizace: Opravdu, pokud je dokument find().limit(1)
načten, zdá se, že pořadí rychlostních rozdílů zmizí. Také jsem nemohl reprodukovat hlavní rychlostní rozdíl s ovladačem JavaScriptu MongoDB. Původně jsem srovnával pomocí MongoDB Java ovladač).
findOne()
je skutečně syntaktický cukr pro find().limit(1)
, vzhledem k tomu, že dokument skutečně načítáte (na rozdíl od pouhého vrácení kurzoru pomocí funkce find()
).
Viz Leftiumova odpověď a aktualizace pro další podrobnosti.
Zdrojový kód může hodně pomoci.
Je to Java, ale myslím, že to může také pomoci).
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;
}
A tady je find()
public DBCursor find( DBObject ref ){
return new DBCursor( this, ref, null, getReadPreference());
}
Jak vidíme, že findOne()
v sobě volá find()
, získá všechny DBOject
v i
a vrátí první.