2010-12-09 11 views
21

Ich verwende MongoDB 1.6.3, um eine große Sammlung (300k + Datensätze) zu speichern. Ich habe einen zusammengesetzten Index hinzugefügt.MongoDB - zu viele Daten für sort() ohne Indexfehler

db['collection_name'].getIndexes() 
[ 
    { 
     "name" : "_id_", 
     "ns" : "db_name.event_logs", 
     "key" : { 
      "_id" : 1 
     } 
    }, 
    { 
     "key" : { 
      "updated_at.t" : -1, 
      "community_id" : 1 
     }, 
     "ns" : "db_name.event_logs", 
     "background" : true, 
     "name" : "updated_at.t_-1_community_id_1" 
    } 
] 

aber wenn ich versuche, diesen Code auszuführen:

db['collection_name'] 
    .find({:community_id => 1}) 
    .sort(['updated_at.t', -1]) 
    .skip(@skip) 
    .limit(@limit) 

Ich erhalte:

Mongo :: OperationFailure (zu viele Daten für sort() ohne Index Fügen Sie einen Index hinzu oder geben Sie eine kleinere Grenze an.

Was mache ich falsch?

Antwort

14

Versuchen Sie, {community_id: 1, 'updated_at.t': -1} Index hinzuzufügen. Es muss zuerst nach community_id suchen und dann sortieren.

+2

Die Sortierspalte muss die letzte Spalte im Index sein. http://www.mongodb.org/display/DOCS/Indexing+Advice+and+FAQ#IndexingAdviceandFAQ-1.TheortcolumnmussdieletzteSpalte, die imIndexenthaltenwurde. –

4

So "fühlt" sich an, als ob Sie den Index verwenden, aber der Index ist eigentlich ein zusammengesetzter Index. Ich bin mir nicht sicher, ob die Sorte "schlau genug" ist, nur den Teilindex zu verwenden.

So zwei Probleme:

  1. auf Ihre Abfrage basiert, würde ich community_id als erster Teil des Index setzen, nicht die zweite. updated_at.t klingt wie ein Feld, in dem Sie Bereichsabfragen ausführen. Indizes funktionieren besser, wenn die Bereichsabfrage das zweite Bit ist.
  2. Wie viele Einträge werden von community_id => 1 zurückkommen? Wenn die Anzahl nicht groß ist, können Sie vielleicht einfach nur ohne Index sortieren.

So können Sie den Index um zu wechseln, und Sie können beide verwenden community_id und updated_at.t haben, um die Art zu ändern. Ich weiß, dass es überflüssig scheint, aber beginnen Sie dort und überprüfen Sie die Google Groups, wenn es immer noch nicht funktioniert.

2

Auch mit einem Index, ich denke, Sie können diesen Fehler immer noch erhalten, wenn Ihr Ergebnissatz 4 MB überschreitet.

Sie die Größe dieses, indem Sie in die mongodb Konsole und dabei sehen:

show dbs 
# pick yours (e.g., production) 
use db-production 
db.articles.stats 

ich mit den Ergebnissen wie folgt endete:

{ 
"ns" : "mdalert-production.encounters", 
"count" : 89077, 
"size" : 62974416, 
"avgObjSize" : 706.9660630690302, 
"storageSize" : 85170176, 
"numExtents" : 8, 
"nindexes" : 6, 
"lastExtentSize" : 25819648, 
"paddingFactor" : 1, 
"flags" : 1, 
"totalIndexSize" : 18808832, 
"indexSizes" : { 
    "_id_" : 3719168, 
    "patient_num_1" : 3440640, 
    "msg_timestamp_1" : 2981888, 
    "practice_id_1" : 2342912, 
    "patient_id_1" : 3342336, 
    "msg_timestamp_-1" : 2981888 
}, 
"ok" : 1 
} 
0

Mit einer Cursor Chargengröße, die zu groß ist wird diesen Fehler verursachen. Das Festlegen der Stapelgröße begrenzt nicht die Menge der Daten, die Sie verarbeiten können, sondern beschränkt lediglich die Menge an Daten, die von der Datenbank zurückgegeben werden. Wenn Sie das Batch-Limit durchlaufen und das Batch-Limit erreichen, führt der Prozess einen weiteren Trip zur Datenbank durch.