OriginChainDB docs
examples · vector · 8 / 13

8. Delete a vector

← Vector examples

what this does

DELETE /v1/tenants/:t/vector/:table/:vec_id removes one embedding. It answers 200 in both cases - the body's deleted field carries the outcome, so deleting an id that was never there is a no-op rather than a 404. POST /v1/tenants/:t/vector/:table/delete-bulk is the same operation over a list of ids in a single write.

when to use it

  • An erasure request - the row is gone from your source of truth and its embedding has to go with it.
  • Re-embedding under a new model: delete the old vectors before writing the new ones, so a stale vector cannot outrank a fresh one.
  • Cleaning up after a bad ingest, where you know the ids and want them gone in one call rather than 10,000 requests.

the request

DELETE /v1/tenants/:t/vector/:table/:vec_id
curl -X DELETE "https://$OC_HOST/v1/tenants/$OC_TENANT/vector/shop.products/sku-9281" \
  -H "Authorization: Bearer $OC_TOKEN"

what you get back

{
  "deleted": true
}

deleted is false when nothing was stored under that id. Nothing is written on that path, so a retry costs you a round trip and nothing else.

query parameters

FieldRequiredNotes
indexno"hnsw" (default), "ivf" or "ivf_pq". Picks which index family the delete dispatches into.
repairnoHNSW only. true re-links the deleted node's neighbours across the hole instead of leaving a tombstone. Ignored on the IVF and IVF-PQ arms, which shrink their posting lists cleanly.

deleting in bulk

POST /v1/tenants/:t/vector/:table/delete-bulk
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/vector/shop.products/delete-bulk" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "ids":    ["sku-9281", "sku-1144", "sku-5520"],
    "index":  "hnsw",
    "repair": true
  }'

what bulk delete returns

{
  "deleted_count": 2,
  "missing_count": 1
}

The two counts always sum to the number of distinct ids you sent - duplicates inside one call are de-duplicated server-side and count once.

how it works

On the HNSW arm a delete tombstones the node: the graph slot stays, the embedding goes. repair: true additionally re-links the neighbours across the hole, at a higher per-call cost. In bulk that repair runs as a single sweep at the end of the batch rather than once per id.

On the IVF and IVF-PQ arms the id is evicted from its cell's posting list and the payload is deleted; there is no topology to repair. Every successful delete also decrements the tenant's stored-embedding counter, so the quota tracks embeddings currently resident rather than embeddings ever written.

A bulk delete writes one entry to the destructive-operations audit trail carrying the counts, the index family and whether repair ran. The ids themselves are deliberately not logged - a vector id is customer-chosen and routinely a document or user key.

common mistakes

  • Treating a missing id as an error. Both routes return 200 for an id that was not there. Assert on deleted / deleted_count, not on the status code.
  • Forgetting index on an IVF table. The dispatch defaults to HNSW. Delete an IVF row without ?index=ivf and the cell posting still lists it.
  • Sending more than 10,000 ids. That is the per-request cap and it is a 400, not a truncation. Page your own list.
  • Expecting repair to help an IVF delete. It is accepted on both arms so one client shape works everywhere, but it only does anything on HNSW.
  • Very long ids. A vector id over 1 KiB is refused with 400 - the limit exists so the hash and write path stay bounded.