2014-10-15 9 views
9

È possibile ottenere un singolo documento su db.collection.aggregate come in db.collection.findOne?È possibile ottenere risultati singoli in forma aggregata?

+1

In realtà non è chiaro che cosa si sta chiedendo qui. Nello specifico dovresti spiegare cosa vuoi fare. A proposito la risposta data finora è sbagliata per la maggior parte dei casi. –

risposta

2

È possibile aggiungere lo stadio $match alla pipeline di aggregazione. Ma anche se corrisponderà a un solo documento, il risultato sarà comunque un elenco (di lunghezza uno in quel caso). Quindi la risposta è "NO, non è possibile".

12

Sì, è possibile. Basta aggiungere uno stage $group con _id uguale a null. Questo calcolerà i valori accumulati per tutti i documenti di input nel loro complesso. Per esempio.

{ $group: { _id: null, total: { $sum: "$price" }}} 

Oppure, se si vuole ottenere un solo documento dai risultati aggregati, è possibile utilizzare $limit:

{ $limit: 1 } 

UPDATE: Entrambe queste soluzioni restituiscono cursore che avrebbe unico documento. Ma non pensare a findOne come qualcosa di speciale. Recupera anche il cursore e ottiene solo il primo documento (se presente). Ecco mongo implementazione guscio di findOne:

function (query , fields, options){ 
    var cursor = this.find(query, fields, -1 /* limit */, 0 /* skip*/, 
     0 /* batchSize */, options); 

    if (! cursor.hasNext()) 
     return null; 
    var ret = cursor.next(); 
    if (cursor.hasNext()) throw "findOne has more than 1 result!"; 
    if (ret.$err) 
     throw "error " + tojson(ret); 
    return ret; 
} 

Come si può vedere, si utilizza internamente find. Quindi, se vuoi ottenere un singolo documento invece del cursore con un singolo documento, puoi scrivere la tua funzione che fa lo stesso con aggregate. Per esempio.

> DBCollection.prototype.aggregateOne = function(pipeline) { 
    var cur = this.aggregate(pipeline); 
    if (!cur.hasNext()) 
     return null; 
    return cur.next(); 
} 

Usage:

> db.collection.aggregateOne(...) 
+1

Purtroppo ottengo ancora un array con un elemento – Erik

+0

Bullseye (y), molto ben spiegato. –

0

sì è possibile. è necessario utilizzare l'operazione mongodb $match

ex: questo ha funzionato per me.

{ $lookup: { from: 'user', localField: 'userId', foreignField: 'id', as: 'publisherDetails' } }, 
{ $match: { id } } 

mondodb doc's esempio:

db.articles.aggregate(
[ { $match : { id : "132ada123aweae1321awew12" } }, 
    { $lookup: { from: 'user', localField: 'userId', foreignField: 'id', as: 'publisherDetails' } } ] 
); 
Problemi correlati