2016-06-11 11 views
0

Ich möchte eine Sammlung erstellen bestellt erstellen:MongoDB: Wie eine Sammlung von 2 Felder

var ethTransactionSchema = new mongoose.Schema({ 
    blockNumber: Number, 
    transactionIndex: Number, 
    from: String, 
    to: String, 
    data: String 
}); 

Ich brauche transactionIndex geordnete Ergebnisse von Blocknummer, zu erhalten: Wenn zwei Elemente haben die gleiche Blocknummer der transactionIndex wird definieren die Bestellung.

Ich habe eine Indizes:

ethTransactionSchema.index({ blockNumber: 1, transactionIndex: 1 }, { unique: true }); 
ethTransactionSchema.index({ from: 1 }); 

Wenn ich ausführen die Abfrage:

EthTransaction.find({ from: 'address' }).sort({ blockNumber: 1, transactionIndex: 1 }).limit(20) 

und eine weitere Abfrage:

EthTransaction.find(
{ 
    $and: [ 
    { 
     $or: [ { from: 'address1' }, { to: 'address2' } ] 
    }, 
    { 
     $or: [{ blockNumber: { $gt: lastBlockGot } }, { $and: [{ blockNumber: lastBlockGot }, { transactionIndex: { $gt: lastIndexGot } }] }] 
    }] 
} 
).sort({ blockNumber: 1, transactionIndex: 1 }).limit(20) 

I funktioniert perfekt, aber zu langsam. Ich frage mich, wie ich die von blockNumber, transactionIndex bestellten Felder einfügen, damit ich die Ergebnisse ohne die Sortierklausel abrufen kann.

+0

* Ich frage mich, wie füge ich die Felder von blockNumber, transactionIndex, so dass ich die Ergebnisse ohne die Sortierklausel abrufen können. * - Sie können nicht. Es gibt keinen Anzeigenauftrag für Mongo. Wenn Sie es sortiert haben wollen, müssen Sie '.sort()' – cdbajorin

Antwort

2

Die Abfrage nehmen Sie den Index "von", und sortieren Sie im Speicher nach blockNumber und transactionIndex. Sie müssen einen Index erstellen, der aus drei Feldern besteht.

ethTransactionSchema.index({ from:1, blockNumber: 1, transactionIndex: 1 }); 

Edit: im Allgemeinen, wenn Ihre Anfragen zu langsam sind Sie bei uns einen Blick nehmen erklären() Befehl. Im mongoshell führen Sie den Befehl

EthTransaction.find({ from: 'address' }).sort({ blockNumber: 1, transactionIndex: 1 }).explain() 

Allgemeinen expain() am Ende Ihrer Abfragen hinzufügen, um mehr Informationen darüber, wie die Daten erhalten werden zurückgewonnen zu werden. Werfen Sie auch einen Blick auf die offizielle Dokumentation für explain()

+0

verwenden. Ist es nicht möglich, Felder einzufügen, sortiert nach {blockNumber, transactionIndex}? –

+0

Wenn Sie alle Ergebnisse nehmen, dann nach blockNumber und transactionIndex sortieren und schließlich nach 'from' filtern, können Sie den ersten Index verwenden, den Sie erstellt haben, aber die Geschwindigkeit hängt von der Kardinalität des 2-Index ab. Wenn Sie keinen neuen Index inspect erstellen können, beschreiben Sie, welche Lösung für Ihr Schema optimal ist. –

+0

Ich kann einen neuen Index erstellen, aber die echte Sammlung ist nicht genau so (hat auch ein to-Feld) und es gibt eine andere Abfrage, die ein $ oder: [{blockNumber: {$ lt: lastBlockGot}}, {$ und : [{blockNumber: lastBlockGot}, {transactionIndex: {$ lt: lastIndexGot}}]}} um Ergebnisse zu pagen. –

Verwandte Themen