Info
Datum: 27. 11. 2020 um 16:09:58
Schlagworte:
Kategorie: morphium
erstellt von Stephan Bösebeck
logged in
ADMIN
Morphium and Indices
Definieren von Indizes
Normalerweise muss man sich nicht darum kümmern, Indizes direkt in der Mongodb anzulegen. Morphium kümmert sich darum, wenn all Index-Informationen im Code hinterlegt sind:
´´´java @Entity public class MyEntity { @Id private MorphiumId id; @Index private String myIndexedString; @Index(decrement = true) private Integer aNumber; } ´´´
Weitere Informationen darüber kann man in der MorphiumDoku nachlesen.
Index erstellen
Wie schon erwähnt, Morphium kümmert sich um die Erstellung der Indizes und folgt dabei diesen einfachen Regeln:
- bei Schreibzugriffen, prüfe ob dei Collection schon existiert. Wenn nicht, erstelle die Indices, wie im Code hinterlegt
- Wenn die Collection schon exisitert, werden keine Indizes angelegt oder geändert!
Der Grund dahinter ist, dass bei großen Collections, die automatische Erstellung von Indizes wirklich lange dauern kann. Und wenn das beim Schreibzugriff durchgeführt wird, kann das zu problemen führen. Wenn die Collection nicht existiert, wird sie gleich mit den richtigen Indizes erstellt, was eine recht einfache Operation innerhalb der MongodDB ist.
ABer natürlich ist da ein kleiner Haken an der Sache: der Check, ob die Collection existiert, kostst bei jedem Schreibzugriff ein paar ms!
Gerade in Produktiven Umgebungen ist normalerweis nicht so viel Fluktuation an den Daten. Der Vorteil ist, wenn das feature eingeschaltet ist, dass die Indizes auch erstellt werden, wenn man zur Laufzeit eine Collection umbenennt oder dropped.
Falls man dieses Feature nicht benötigt, kann man die automatische erstellung in der MorphiumConfig abschalten:
config.setAutoIndexAndCappedCreationOnWrite(false).
Mit Morphium V4.2.3 kann man den Check auch zu einer einmaligen Prüfung an den Start des Systems verlagern. Damit passiert diese Prüfung nur ein einziges mal:
morphiumConfig.setIndexCappedCheck(IndexCappedCheck.WARN_ON_STARTUP)
In diesem Fall wird auch nur eine Warnung ausgegeben und keine Indizes werden erstellt. Aber man kann noch zwischen mehr Optionen wählen:
NO_CHECK: keine PrüfungWARN_ON_STARTUP: prüfe die Indizes für alle Entities bei Systemstart bzw. wenn Morphium sich mit der MongoDB verbindet.CREATE_ON_WRITE_NEW_COL: erstellen von Indizes bei Schreibzugriff, wenn die Collection nicht vorhanden ist (Defaultverhalten)CREATE_ON_STARTUP: Indizes beim Start prüfen und ggf. erstellen.
Hinweis: es gibt keine Option zum Warnen bei schreibzugriff, da das den zugriff stark verlangsamen würde. Gleiches gilt für die Erstellung von indizes bei jedem Schreibzugriff! Falls man so etwas implementieren muss, kann man sich entweder mit storageListener behelfen oder das über die LifeCycle-Methoden wie z.B. PreStore erledigen.
Warnungen für fehlende Indices sehen in etwa so aus:
Collection 'person' for entity 'de.caluga.test.mongo.suite.TextIndexTest$Person' does not exist.
Capped collections
Morphium kombiniert die Erstellung / Prüfung von indizes und das "Cappen" von Collections. Das bedeutet, bei default einstellungen, werden bei Schreibzugriff sowohl die Indizes erstellt als auch sichergestellt, dass die Capped-Einstellungen berücksichtigt werden. Das bedeutet auch, dass eine Collection ggf. in eine CappedCollection umgewandelt wird (abhängig von den eigenen einstellungen).
programmatically creating indices
Am einfachsten kann man Indizes erstellen über die Methode: ensureIndicesFor(ENTITYCLASS).
Das erstellt alle Indizes gemäß den definitionen mit @Index.
Möchte man auch die Collection cappen möchte
If you also want to ensure, the corresponding collection is capped, if defined accordingly, call morphium.ensureCapped(ENTITYCLASS).
Both methods will not create indices or capped collections, if no index is defined in code. But it will call ensureIndex on mongodb.
Hint: when an index is created for a non existend collection, there will be an empty collection in mongodb.
But you can also create indices more manually:
´´´java
public
Die index Map enthält das Document, welches den Index beschreibt, genau so, wie die Mongodb das liefert. In Options werden die optionen für diesen Index angegeben.
´´´java morphium.ensureIndex(UncachedObject.class, "uncached_object",Utils.getMap("counter",1),Utils.getMap("unique","true"),null); ´´´
Informationen über fehlende Indices bekommen
Um nur die Informationen über fehlende Indizes eines spezeillen Entity zu bekommen, kann man diese ab Morphiumg V4.2.3 abfragen:
´´´java Map<Class<?>, List<Map<String, Object>>> missing = morphium.checkIndices(); ´´´ das liefert eine Map, deren Key die Entity Klasse ist und eine liste der Fehlenden Indexdefinitionen als Wert. Diesen Wert kann man nutzen, um einen Index manuell zu erstellen:
´´´java Map<Class<?>, List<Map<String, Object>>> missing = morphium.checkIndices(); morphium.ensureIndex(EntObject.class,missing.get(EntObject.class).get(0)); ´´´
ATTENTION:
checkIndices()fügt auch Informationen über fehlende Capped-Settings in die Ergebnis Map ein!checkIndices()läuft durch den ganzen Classpath um Entities zu finden, das kann ein paar Millisekunden dauern. Falls man die Anzahl der zu scannenden Klassen reduzieren will, kann man einen Filter mitgeben:checkIndices(classInfo -> !classInfo.getPackageName().startsWith("de.caluga.morphium"));
Zusammenfassung
Die Performanz von Datenbanken ist sehr abhängig von der richtigen Erstellung der Indizes. Und genau dabei kann Morphium helfen, da man sich als Entwickler nicht mehr darum kümmern muss, wie indizes in Mongo erstellt werden, sondern nur noch allgemein, was Indiziert werden sollte.