2015-01-06 16 views
16

Ich schaffe Index in mongodb mit 10 Millionen Datensätze erstellen, aber folgende FehlerKann nicht Index in mongodb "Schlüssel zu groß, um Index"

db.logcollection.ensureIndex({"Module":1}) 
{ 
     "createdCollectionAutomatically" : false, 
     "numIndexesBefore" : 3, 
     "ok" : 0, 
     "errmsg" : "Btree::insert: key too large to index, failing play.logcollection.$Module_1 1100 { : \"RezGainUISystem.Net.WebException: The request was aborted: The request was canceled.\r\n at System.Net.ConnectStream.InternalWrite(Boolean async, Byte...\" }", 
     "code" : 17282 
} 

Bitte helfen Sie mir, wie in mongodb zu Create,

+0

Sie versuchen, Index für "Modul" zu löschen. Ich denke, dein Inhalt ist zu groß für den normalen Index. – NHK

Antwort

24

MongoDB erstellt keinen Index für eine Auflistung, wenn der Indexeintrag für ein vorhandenes Dokument die (1024 Byte) überschreitet. Sie können jedoch ein hashed index oder text index stattdessen erstellen:

db.logcollection.ensureIndex({"Module":"hashed"}) 

oder

db.logcollection.ensureIndex({"Module":"text"}) 
+1

danke, es funktionierte für mich, aber Leistung von Hash-Index sehr langsam, meine Abfrage ist db.logcollection.find ({"Module": "RezGainUI"}). Count(). es dauert ungefähr 18 Sekunden, um zu zählen –

+1

Finden Sie die Überlängenwerte und verkürzen Sie sie, wenn Sie können. Dann können Sie normalen Index erstellen – anhlc

+0

Sorry, ich bin neu in mongodb Bitte führe mich, wie es geht –

13

Sie können schweigen dieses Verhalten durch Beispiel mit dem folgenden Befehl starten mongod:

mongod --setParameter failIndexKeyTooLong=false 

oder durch die Ausführung folgender Befehl von mongoShell

db.getSiblingDB('admin').runCommand({ setParameter: 1, failIndexKeyTooLong: false }) 

Wenn Sie sichergestellt haben, dass Ihr Feld den Grenzwert sehr selten überschreitet, dann ist eine Möglichkeit, dieses Problem zu lösen, indem Sie Ihr Feld (das den Index außerhalb des Grenzwerts verursacht) in byteweise Teile aufteilen < 1KB z. für Feld val würde ich es in Tupel von Feldern val_1, val_2 und so weiter aufteilen. Mongo speichert Text als utf-8 gültige Werte. Das bedeutet, dass Sie eine Funktion benötigen, die UTF-8-Strings richtig aufteilen kann.

def split_utf8(s, n): 
    """ 
    (ord(s[k]) & 0xc0) == 0x80 - checks whether it is continuation byte (actual part of the string) or jsut header indicates how many bytes there are in multi-byte sequence 

    An interesting aside by the way. You can classify bytes in a UTF-8 stream as follows: 

    With the high bit set to 0, it's a single byte value. 
    With the two high bits set to 10, it's a continuation byte. 
    Otherwise, it's the first byte of a multi-byte sequence and the number of leading 1 bits indicates how many bytes there are in total for this sequence (110... means two bytes, 1110... means three bytes, etc). 
    """ 
    s = s.encode('utf-8') 
    while len(s) > n: 
     k = n 
     while (ord(s[k]) & 0xc0) == 0x80: 
      k -= 1 
     yield s[:k] 
     s = s[k:] 
    yield s 

Dann können Sie Ihre Verbindung Index definieren:

db.coll.ensureIndex({val_1: 1, val_2: 1, ...}, {background: true}) 

oder mehrere Indizes für jeden val_i:

db.coll.ensureIndex({val_1: 1}, {background: true}) 
db.coll.ensureIndex({val_1: 2}, {background: true}) 
... 
db.coll.ensureIndex({val_1: i}, {background: true}) 

Wichtig: Wenn Sie Ihr Feld in Verbindung Index in Betracht ziehen, dann sei vorsichtig mit dem zweiten Argument für split_utf8 Funktion. Bei jedem Dokument müssen Sie die Summe der Bytes jedes Feldwerts entfernen, die Ihren Indexschlüssel enthalten, z. für den Index (a: 1, b: 1, Val: 1) 1024 - sizeof(value(a)) - sizeof(value(b))

In allen anderen Fällen verwenden entweder hash oder text Indizes.

+0

liegt. Das Erstellen eines zusammengesetzten Indexes würde nicht funktionieren, da die 1024-Größenbeschränkung für die Größe des gesamten [Indexschlüssels] gilt (https: // docs.mongodb.com/v3.2/reference/limits/#Index-Key-Limit), nicht jedes Feld darin. – JohnnyHK

+0

@JohnnyHK du hast recht. Siehe "Wichtige" Hinweise. Ich habe es verfeinert. –

+1

In meinem Projekt habe ich 4-5 dimensionale Indizes und dieser Ansatz funktioniert glänzend :) –

Verwandte Themen