re
re6d ago

How can I index/filter my database for tags (array of strings)

I have a filter selector, which returns an individual filter as a string. I'm trying to use this to index through my database and return results that have that as a tag. However, I can't seem to figure this out through indexing. Am I missing something? Here's my schema code and my current boilerplate code:
tournaments: defineTable({
name: v.string(),
description: v.optional(v.string()),
thumbnail: v.optional(v.string()),
type: v.union(v.literal('IMAGE'), v.literal('VIDEO')),
tags: v.array(v.string()),
userId: v.id('users'),
views: v.number(),
likes: v.number(),
updatedAt: v.number(),
})
.index('by_user_id', ['userId'])
.index('by_views', ['views'])
.index('by_updatedAt', ['updatedAt'])
.index('by_tags', ['tags']),
tournaments: defineTable({
name: v.string(),
description: v.optional(v.string()),
thumbnail: v.optional(v.string()),
type: v.union(v.literal('IMAGE'), v.literal('VIDEO')),
tags: v.array(v.string()),
userId: v.id('users'),
views: v.number(),
likes: v.number(),
updatedAt: v.number(),
})
.index('by_user_id', ['userId'])
.index('by_views', ['views'])
.index('by_updatedAt', ['updatedAt'])
.index('by_tags', ['tags']),
and my query:
export const getTournaments = query({
args: {
filter: v.optional(v.string()),
},
handler: async (ctx, args) => {
const filter = args.filter ?? 'Latest';

console.log(filter);
switch (filter) {
default:
// For any other filter, assume it's a tag and use the search index.
const filteredTournaments = await ctx.db
.query('tournaments')
.withIndex('by_tags', (q) => q.eq('tags', filter))
.collect();

console.log('filtered tournaments', filteredTournaments);
return filteredTournaments;
export const getTournaments = query({
args: {
filter: v.optional(v.string()),
},
handler: async (ctx, args) => {
const filter = args.filter ?? 'Latest';

console.log(filter);
switch (filter) {
default:
// For any other filter, assume it's a tag and use the search index.
const filteredTournaments = await ctx.db
.query('tournaments')
.withIndex('by_tags', (q) => q.eq('tags', filter))
.collect();

console.log('filtered tournaments', filteredTournaments);
return filteredTournaments;
Am I doing something wrong with how I index? For exampl,e I get the error on the filter variable within withIndex:
Argument of typing 'string' is not assignable to parameter of type 'string[]'
Thanks!
3 Replies
Convex Bot
Convex Bot6d ago
Thanks for posting in <#1088161997662724167>. Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets. - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.) - Use search.convex.dev to search Docs, Stack, and Discord all at once. - Additionally, you can post your questions in the Convex Community's <#1228095053885476985> channel to receive a response from AI. - Avoid tagging staff unless specifically instructed. Thank you!
re
reOP6d ago
Additionally, It works with this code:

const tournaments = await ctx.db.query('tournaments').collect();
const filteredTournaments = tournaments.filter((m) => m.tags.includes(filter));
console.log('filtered tournaments', filteredTournaments);
return filteredTournaments;

const tournaments = await ctx.db.query('tournaments').collect();
const filteredTournaments = tournaments.filter((m) => m.tags.includes(filter));
console.log('filtered tournaments', filteredTournaments);
return filteredTournaments;
but is this the most optimal? Convex AI recommends using a join table appraoch, having a separate table for tags - but is this the best way?
Abhishek
Abhishek6d ago
Exactly storing them in different table will be much faster and recommend way

Did you find this page helpful?