Abdulramon JemilA
Convex Communityโ€ข2y agoโ€ข
1 reply
Abdulramon Jemil

Bad example in docs

In the vector search docs (https://docs.convex.dev/search/vector-search#using-a-separate-table-to-store-vectors), there is the following example:

export const fetchMovies = query({
  args: {
    ids: v.array(v.id("movieEmbeddings")),
  },
  handler: async (ctx, args) => {
    const results = [];
    for (const id of args.ids) {
      const doc = await ctx.db
        .query("movies")
        .withIndex("by_embedding", (q) => q.eq("embeddingId", id))
        .unique();
      if (doc === null) {
        continue;
      }
      results.push(doc);
    }
    return results;
  },
});


This example uses
await
inside of a
for
loop, which I believe is from convex-demos/vector-search (https://github.com/get-convex/convex-demos/blob/d7e772bf8dcf694a075556c639a0c645b833e4a4/vector-search/convex/movies.ts#L110), and this is, in general a bad practice, and it becomes evident when there's a large number of
id
s to enumerate, resulting in very long response times. A better solution would be to use Promise.all and Array.prototype.filter as follows:

export const fetchMovies = query({
  args: {
    ids: v.array(v.id("movieEmbeddings"))
  },
  handler: async (ctx, args) => {
    const results = await Promise.all(
      args.ids.map((id) =>
        ctx.db
          .query("movies")
          .withIndex("by_embedding", (q) => q.eq("embeddingId", id))
          .unique()
      )
    )
    return results.filter((result) => result !== null)
  }
})
Was this page helpful?