#Convex Query filters with array inputs
15 messages · Page 1 of 1 (latest)
Filtering arrays in Convex queries is a common need, but it requires specific approaches since Convex doesn't directly support array containment operations in its query filter syntax.
Filtering Arrays in Convex
When you want to filter documents based on array contents, you have several options:
Option 1: Filter in TypeScript after collection
The simplest approach is to fetch all documents and then filter them using TypeScript:
export const postsWithTag = query({
args: { tag: v.string() },
handler: async (ctx, args) => {
const allPosts = await ctx.db.query("posts").collect();
return allPosts.filter((post) => post.tags.includes(args.tag));
},
});
This works but requires reading the entire table first, which can be inefficient for large datasets Using TypeScript to Write Complex Query Filters.
Option 2: Use the filter helper from convex-helpers
For better performance when you only need some results, you can use the filter helper from the convex-helpers package:
import { filter } from "convex-helpers/server/filter";
export const firstPostWithTag = query({
args: { tag: v.string() },
handler: (ctx, args) => {
return filter(
ctx.db.query("posts"),
(post) => post.tags.includes(args.tag),
).first();
},
});
This allows you to use methods like .first(), .unique(), .take(n), or .paginate(opts) without collecting all documents first Using TypeScript to Write Complex Query Filters.
Option 3: Use indexes (recommended for production)
For production applications with large datasets, the recommended approach is to use indexes:
// Schema
export default defineSchema({
posts: defineTable({
body: v.string(),
tags: v.array(v.string()),
}),
tagged_posts: defineTable({
tag: v.string(),
post: v.id("posts"),
}).index("by_tag", ["tag"]),
});
// Query
export const postsWithTag = query({
args: { tag: v.string() },
handler: async (ctx, args) => {
const taggedPosts = await ctx.db.query("tagged_posts")
.withIndex("by_tag", (q) => q.eq("tag", args.tag))
.collect();
return await Promise.all(
taggedPosts.map((taggedPost) => ctx.db.get(taggedPost.post))
);
},
});
This approach creates a separate table that maps tags to posts, allowing efficient lookups Using TypeScript to Write Complex Query Filters.
Important Considerations
-
Bandwidth usage: Be aware that using
.filter()after.collect()still counts toward your database bandwidth quota, as all documents are read from the database before filtering Discord support thread. -
Performance: For small datasets (a few hundred documents), filtering in TypeScript is fine for prototyping. For larger datasets, indexes are essential for performance Using TypeScript to Write Complex Query Filters.
-
Alternative approach: You can also use full-text search indexes if your data structure allows it Using TypeScript to Write Complex Query Filters.
Choose the approach that best fits your application's needs and data volume.
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
@stone fjord Kapa.ai is still learning and improving, please let me know how I did by reacting below.
const retriever = vectorStore.asRetriever({
filter: {
filter: (q) =>
q.or(q.eq('chatId', chatId), q.eq('fileId', fileId ?? '')),
},
});
I want to use an array of fileIds rather than a filedId
@frigid osprey
Let me check the knowledge base for you again. One moment! :books:
Sorry @stone fjord, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
Let me check the knowledge base for you again. One moment! :books:
Sorry @stone fjord, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
Are you good now AI @frigid osprey
Let me check the knowledge base for you again. One moment! :books:
I'm designed to help with questions about Convex, the backend development platform. Your message doesn't appear to contain a specific question about Convex features, functionality, or implementation.