Skip to main content

Zeilen-Lebenszyklus

Drei Schritt-Arten decken den id-basierten Lebenszyklus ab, alle über POST /v1/namespaces/{ns}/query:
  • UpsertN – vollständiger Zeilenersatz mit der externen id als Schlüssel. Bestehende Zeilen mit dieser id werden gelöscht, dann wird die neue Zeile eingefügt. Ersetzen, nicht zusammenführen: ein vektorloser Upsert einer vektorierten Zeile verwirft den Vektor.
  • SetProps – überschreibt bestimmte Schlüssel eines gematchten Streams (Starten Sie die Abfrage mit NWhere); ein null-Wert entfernt den Schlüssel. id selbst kann nicht geändert werden – das ist ein UpsertN. Richtig für gelegentliche Attribut-Umschreibungen, falsch für Zähler pro Abfrage.
  • DeleteN – löscht einen gematchten Stream (NWhereDeleteN) oder übergeben Sie ids für direkte externe-id-Löschungen.

Vektorkodierungen

Pro Zeile eine von zwei Wire-Kodierungen (beide senden ist ein 400):
vector_b64 ist base64 des Vektors als Little-Endian-f32-Array – ~4× kleiner auf der Leitung und mit memcpy statt JSON-Zahlen-Parsing dekodiert. Python-Encoder:
Beide Kodierungen erzeugen bit-identisch gespeicherte Vektoren und identische Suchergebnisse. Die Dimension wird durch den ersten vektorierten Schreibvorgang festgelegt; eine Abweichung ist ein 400.

Bulk-Ingest: POST /v1/namespaces/{ns}/bulk-vectors

Der Hochdurchsatz-Seed-Pfad – ein binärer Frame pro Anfrage (Content-Type: application/octet-stream): ein kleiner JSON-Header (dims, label, ids, gemeinsame props), gefolgt von zeilenweise L2-normierten fp16-Werten. Im Vergleich zu JSON+base64 vermeidet dies das mehrfache Neucodieren von Multi-GB-Payloads.

Neustart-sicheres Laden

Fortsetzbare Loader übergeben ?expected_generation=<G>&expected_rows=<N>. Der Frame wird nur akzeptiert, wenn der Namespace exakt in diesem Zustand ist:
  • Derselbe Frame bereits committet → 200 mit "replayed": true und dem passenden request_fingerprint – keine doppelten Zeilen.
  • Anderes Payload an derselben Position → 409 write_conflict.
  • Erfolgreiche bedingte Schreibvorgänge geben request_fingerprint, rows_before, rows_after zurück – setzen Sie den Checkpoint Ihres Batches erst, nachdem Sie eine dieser Empfangsbestätigungen erhalten haben.
Das macht „Absturz, Neustart, erneut Senden” zur gesamten Fortsetzungs-Story: keine Importjobs, die zu betreuen sind.

Kompaktierung

Die Auto-Kompaktierung ist geometrisch, sodass die gesamte Kompaktierungsarbeit linear in eingelesenen Bytes bleibt. Beenden Sie jede Bulk-Ladung mit einer expliziten Kompaktierung – senden Sie "compact": true auf oberster Ebene der letzten Schreibanforderung:
Die Antwort meldet "compacted": true/false. Die Kompaktierung baut auch den ANN-Index auf, sobald die Tabelle groß genug ist; nach dem Index-Snapshot geschriebene Zeilen werden per Brute Force in die Ergebnisse eingefügt, sodass die Aktualität nie geopfert wird.

Deduplizierung einer Bulk-Quelle

Bulk-Frames hängen bewusst blind an – eine Quelle, die doppelte ids trägt, lässt diese stillschweigend landen, und Duplikate verbrauchen top-k-Slots. {"DedupN": {}} bringt einen Store wieder in den Vertrag der externen id-Eindeutigkeit (behält die zuletzt geschriebene Zeile pro id), und {"DedupN": {"dry_run": true}} ist das reine Volkszählungs-Audit, das jede Bulk-Ladung ausführen sollte, wenn ihre Quelle keine id-Eindeutigkeit nachweisen kann – eine übereinstimmende Gesamtzeilenanzahl kann keine darin versteckten Duplikate offenlegen.

Retry-Regeln

Lesevorgänge können nach einem Transportfehler immer wiederholt werden. Bei Schreibvorgängen sind nur bedingte Bulk-Frames automatisch wiederholbar (identischer Frame + CAS-Parameter → Original-Empfangsbestätigung oder replayed: true). Wiederholen Sie niemals blind einen unbedingten Schreibvorgang nach einer verlorenen Antwort – gleichen Sie den Zustand zuerst ab.