ElasticSearch Email als ID verwenden?

Falc410

Vice Admiral
Registriert
Juni 2006
Beiträge
6.640
Ich bin totaler Anfänger was Elasticsearch angeht.

Spricht etwas dagegen, Emails als ID zu verwenden? Ich habe hier Datensätze die keine eindeutige ID haben, aber eindeutige Emailadressen. Ich möchte wenn ich morgen einen neuen Datensatz habe und diesen importierre, dass eben bereits vorhandene Datensätze zu den Emailadressen aktualisiert werden. Oder sollte ich lieber die Emails hashen, da _id nur max 512 Zeichen haben darf?
 
Aus technischer Sicht spricht hier wohl nichts dagegen, 512 Zeichen sollten reichen.
Aus fachlicher Sicht ist meine Erfahrung mittlerweile, dass es "einfacher" ist, wenn man überall mit Ids arbeiten kann, z.B., wenn es in Zukunft möglich sein soll die E-Mail Adresse eines Datensatzes zu ändern.
 
  • Gefällt mir
Reaktionen: pcBauer
Ich weiss halt nicht was Best Practice ist. Wenn ich _id nicht angebe, wird ja jedesmal ein neuer Datensatz erstellt - in dem Fall hätte ich mehrere Versionen vom Datensatz und die Datenbank läuft voll.
Also brauche ich irgendeine unique ID - entweder die Mailadresse selbst oder ich hashe ich vorher. Die Email ist noch einmal zusätzlich als Feld abgespeichert.
 
Ich würde sie trotzdem hashen, da sie beim indexieren ja teil der URL wird. Da mit Sonderzeichen zu arbeiten finde ich unschön und u.U. auch fehleranfällig. Ansonsten spricht aus meiner Sicht nichts dagegen sie als ID zu nehmen.

Erstell dir einen Datentyp spezifischen Index, dann kannst du andere Daten auch mit anderer (sinnvoller) id indexieren.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Falc410
Du kannst auch ein Update mit einer Query verbinden. Sprich: "Update mir den Datensatz, dessen Feld 'mail' 'xy' ist"
 
  • Gefällt mir
Reaktionen: netzgestaltung und Falc410
@Bagbag Das ist aber zusätzlicher Aufwand. Wenn ich die Daten einfach so hinwerfen kann und automatisch ein Upsert gemacht wird, ist es doch deutlich einfacher.

Wenn man irgendwelche vordefinierten UIs für die Datenintegration nutzt (z.B. Azure DataFactory) ist es so auch am Einfachsten und man muss keine Kopfstände machen.
 
Hash die E-Mail, damit bekommst du eine bessere Verteilung der Werte hin. Unterschiede merkst wahrscheinlich erst ab diversen Millionen Einträgen.
 
Das mit dem Update sieht komplizierter aus, da ich ja vorher eine Query machen muss. So wie ich das sehe, muss ich nämlich auch bei der Update Methode die ID angeben.
Also als Beispiel in Python
Code:
elastic_client.update(index='cars', doc_type=""_doc"", id='Y4UYfmoB6VvZIesyYEBv', body=source_to_update)
 
  • Gefällt mir
Reaktionen: madmax2010
Es gibt auch ein "Update by Query": https://www.elastic.co/guide/en/ela...by-query.html#docs-update-by-query-api-source

Aber ja, deine bisherige Idee ist definitiv einfacher.

Meine Erfahrung hier ist halt, dass nicht-Ids als Ids irgendwann gerne Schwierigkeiten bereiten.

Beispiel:
Da die E-Mail ja eindeutig zu einem User gehört, nehme ich das als Primary Key und ordne seine Bestellungen anhand der Mail zu.
Jetzt ändert der User irgendwann seine Mail, also muss man auch alle Bestellungen aktualisieren, dass diese noch richtig verweisen.

Ich hab mir daher angewöhnt einfach immer eine "richtige" Id zu nutzen, dann braucht man keine kaskadierenden Updates, Hacks (wie hier das Hashen) oder sonst irgendwas.
Natürlich gibt es Ausnahmenfälle wie externe Daten, auf die man keinen Einfluss hat, da muss man dann eben abwägen, wie man damit umgeht.

Konkret für diesen Fall würde das für mich bedeuten: Kannst du bei der Datenquelle Ids hinzufügen? Falls ja, sind damit alle Probleme/Schwierigkeiten dieses Threads behoben.
 
  • Gefällt mir
Reaktionen: netzgestaltung, Falc410 und madmax2010
Nein die Datenquelle hat keine IDs und das einzig eindeutige ist die E-Mail. Die kann sich aber auch nicht ändern.
Genauer gesagt habe ich eine Liste mit E-Mailadressen und frage regelmässig eine API ab und hole mir Informationen zu diesen E-Mailadressen zurück. Da benötige ich immer nur die neueste Information, also den aktuellen Stand.
Habs jetzt mal mit sha256 probiert und sieht gut aus. Datensätze werden überschrieben. Bei 256 sollten Kollisionen auch sehr sehr selten sein
Code:
opensearch.index(index=ES_INDEX, body=json.dumps(item), id=sha256(item["email"].encode('utf-8')).hexdigest(),refresh=True)
 
Zurück
Oben