Looking for a better way to delete vector index entries by a metadata value

I can’t find a way to mass-delete entries, except by id, which means I need to get hold of the ids for a given metadata. E.g. here I want to delete all entries that have a metadata filename === someFileName. This is because I’m splitting text into many chunks and adding those separately to the index.

The way I’m doing it is:

  1. Create a dummy vector
  2. Query the vector index using that vector, and filtering by this metadata value, returning the top 20 values (maximum in beta phase).
  3. Grab the ids and call deleteByIds.
  4. Loop over until there are none left.

This looks really really messy, so I’m wondering if there’s a better way. The only other thing I can think of at the moment is to store the filenames along with their ids in a KV store. But I’m hoping there’s a Vectorize-native way to do it. Here’s my current code:

async function deleteByFilename(filename: string, env: Env, openai: OpenAI) {
  const embedding = await openai.embeddings.create({
    encoding_format: 'float',
    input: 'dummy text',
    model: 'text-embedding-ada-002',

  const vector = embedding?.data?.[0].embedding;
  if (!vector?.length) {
    return new Response('Could not create embedding', { status: 500 });

  let matchesRemaining = true;
  let deleted = [];

  // Ensure all matches are removed (max 20 is returned during beta period)
  while (matchesRemaining) {
    const metadataMatches = await env.VECTORIZE_INDEX.query(vector, {
      topK: 20,
      // @ts-ignore
      filter: {
      returnMetadata: true,

    const ids = metadataMatches.matches.map((match) => match.id);


    await env.VECTORIZE_INDEX.deleteByIds(ids);

    if (metadataMatches.matches.length !== 20) {
      matchesRemaining = false;

  return deleted;