MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

MongoDB-Problemumgehung für Dokumente mit einer Größe von mehr als 16 MB?

Um dieses Problem zu beheben, müssen Sie einige kleine Änderungen an Ihrer Datenstruktur vornehmen. So wie es klingt, müssen Sie Ihre Sensordaten in ein Array in einem einzigen Dokument einbetten, damit Ihre Dokumente die 16-MB-Grenze überschreiten.

Ich würde die Verwendung von GridFS hier nicht empfehlen, ich glaube nicht, dass es die beste Lösung ist, und hier ist der Grund dafür.

Es gibt eine als Bucketing bekannte Technik, die Sie verwenden könnten, um Ihre Sensormesswerte im Wesentlichen in separate Dokumente aufzuteilen und dieses Problem für Sie zu lösen.

So funktioniert es:

Nehmen wir an, ich habe ein Dokument mit einigen eingebetteten Messwerten für einen bestimmten Sensor, das so aussieht:

{
    _id : ObjectId("xxx"),
    sensor : "SensorName1",
    readings : [
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" }
    ]
}

Mit der obigen Struktur gibt es bereits einen großen Fehler, das Messwerte-Array könnte exponentiell wachsen und die Dokumentengrenze von 16 MB überschreiten.

Was wir also tun können, ist, die Struktur leicht so zu ändern, dass sie wie folgt aussieht, um eine count-Eigenschaft einzuschließen:

{
    _id : ObjectId("xxx"),
    sensor : "SensorName1",
    readings : [
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" },
        { date : ISODate("..."), reading : "xxx" }
    ],
    count : 3
}

Die Idee dahinter ist, wenn Sie Ihren Messwert in Ihr eingebettetes Array $pushen, erhöhen Sie ($inc) die Zählvariable für jeden ausgeführten Push. Und wenn Sie diese Aktualisierungsoperation (Push) durchführen, würden Sie einen Filter für diese "count"-Eigenschaft einfügen, der etwa so aussehen könnte:

{ count : { $lt : 500} }

Stellen Sie dann Ihre Update-Optionen so ein, dass Sie "upsert" auf "true" setzen können:

db.sensorReadings.update(
    { name: "SensorName1", count { $lt : 500} },
    {
        //Your update. $push your reading and $inc your count
        $push: { readings: [ReadingDocumentToPush] }, 
        $inc: { count: 1 }
    },
    { upsert: true }
)

Weitere Informationen zu MongoDb Update und der Upsert-Option finden Sie hier:

MongoDB-Update-Dokumentation

Was passiert ist, wenn die Filterbedingung nicht erfüllt ist (d. h. wenn entweder kein vorhandenes Dokument für diesen Sensor vorhanden ist oder der Zählerstand größer oder gleich 500 ist – weil Sie ihn jedes Mal erhöhen, wenn ein Element verschoben wird), ein neuer Dokument erstellt und die Messwerte werden nun in dieses neue Dokument eingebettet. Sie werden also niemals die 16-MB-Grenze erreichen, wenn Sie dies richtig machen.

Wenn Sie jetzt die Datenbank nach Messwerten eines bestimmten Sensors abfragen, erhalten Sie möglicherweise mehrere Dokumente für diesen Sensor (statt nur einem mit allen darin enthaltenen Messwerten). Wenn Sie beispielsweise 10.000 Messwerte haben, erhalten Sie 20 Dokumente zurück , jeweils mit 500 Messwerten.

Sie können dann die Aggregationspipeline und $unwind verwenden, um Ihre Messwerte so zu filtern, als wären sie ihre eigenen individuellen Dokumente.

Weitere Informationen zum Entspannen finden Sie hier, es ist sehr nützlich

MongoDB-Unwind

Ich hoffe, das hilft.