2013-01-12 19 views
5

ho questi documenti in una collezione:Combinare due campi di diversi documenti in MongoDB

{topic : "a", 
    messages : [ObjectId("21312321321323"),ObjectId("34535345353"),...] 
    }, 
    {topic : "b, 
    messages : [ObjectId("1233232323232"),ObjectId("6556565656565"),...] 
    } 

Esiste una possibilita 'di ottenere un risultato con la combinazione di campi messaggi? Mi piace per ottenere questo, ad esempio:

 {[ 
     ObjectId(""),ObjectId(""),ObjectId(""),ObjectId("") 
    ]} 

ho pensato che questo è stato possibile con MapReduce ma nel mio caso i documenti non ha nulla in comune. In questo momento sto facendo questo nel backend usando javascript e loop, ma penso che questa non sia l'opzione migliore. Grazie.

risposta

4

È possibile utilizzare l'operatore $group nello Aggregation Framework. Per usare l'Aggregation Framework dovrai essere sicuro di essere in esecuzione su MongoDB 2.2 o più recente, ovviamente.

Se utilizzato con $push otterrete tutti gli elenchi di messaggi concatenati insieme.

db.myCollection.aggregate({ $group: { messages: { $push: '$messages' } } }); 

Se usato con $addToSet si ottengono solo i valori distinti.

db.myCollection.aggregate({ $group: { messages: { $addToSet: '$messages' } } }); 

E se si desidera filtrare verso il basso i documenti candidati prima, è possibile utilizzare $match.

db.myCollection.aggregate([ 
    { $match: { topic: { $in: [ 'a', 'b' ] } } }, 
    { $group: { matches: { $sum: 1 }, messages: { $push: '$messages' } } } 
]); 
+0

Grazie, penso che funzionerà, sto aggiornando il mio mongodb. –

1

Un'opzione è utilizzare il framework di aggregazione.

Tuttavia, se si prevede di ottenere un numero elevato di risultati (oltre a un risultato "leggero"), un documento risultato di dimensioni superiori a 16 MB o una memoria di sistema eccessiva, è necessario eseguire un ciclo di gli oggetti nella raccolta e concatenano manualmente i risultati (come suggerisci di fare ora) o rischi che mongodb generi un'eccezione.

limiti di aggregazione possono essere trovati in fondo a questa pagina:

http://docs.mongodb.org/manual/applications/aggregation/

Dati i limiti, si può decidere di utilizzare solo find con una proiezione per tornare solo messages.

(E con qualcosa di simile, ti consiglio vivamente di fare alcuni benchmark delle prestazioni per confrontare le opzioni con i tuoi dati sui tuoi server come suggerirebbe "Internet" in questo momento che alcune persone hanno trovato il supporto Aggregation più lento rispetto ad altre tecniche).

+0

Sì, esistono limitazioni al framework di aggregazione. La soluzione giusta, soprattutto su larga scala, richiede il bilanciamento dei compromessi. Anche se non si raggiungono i limiti del framework, potrebbe essere più scalabile fare l'unione in-memory degli elenchi nel client piuttosto che nel server del database. – jared

Problemi correlati