Doogibo
Doogibo•4w ago

Conditionally Building Queries

Having trouble figuring out how to do the following without TypeScript complaining. I want to start a query like this:
let query = ctx.db.query("requests");
let query = ctx.db.query("requests");
And conditionally add to it. Then later for an indexed query:
query = query.withIndex('by_this_and_that', q => {
const baseQuery = q.eq('this', user._id);
return status ? baseQuery.eq('that', status) : baseQuery;
})
query = query.withIndex('by_this_and_that', q => {
const baseQuery = q.eq('this', user._id);
return status ? baseQuery.eq('that', status) : baseQuery;
})
Then later, an optional in memory filtering.
query = query.filter(q => {
if (status) {
return q.neq(q.field('status'), 'DRAFT');
}
return q;
})
query = query.filter(q => {
if (status) {
return q.neq(q.field('status'), 'DRAFT');
}
return q;
})
Something like that anyway. But I run into: is missing the following properties from type 'QueryInitializer<{ document: { _id: Id<"requests">; _creationTime: .... etc.
8 Replies
Convex Bot
Convex Bot•4w 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!
lee
lee•4w ago
Does this pattern help?
const preIndexQuery = ctx.db.query("tbl");
let postIndexQuery: Query = preIndexQuery;
if (useIndex) {
postIndexQuery = preIndexQuery.withIndex("foo", q=>...);
}
if (useFilter) {
postIndexQuery = postIndexQuery.filter(q=>...);
}
let orderedQuery: OrderedQuery = postIndexQuery;
if (desc) {
orderedQuery = postIndexQuery.order("desc");
}
const results = await orderedQuery.collect();
const preIndexQuery = ctx.db.query("tbl");
let postIndexQuery: Query = preIndexQuery;
if (useIndex) {
postIndexQuery = preIndexQuery.withIndex("foo", q=>...);
}
if (useFilter) {
postIndexQuery = postIndexQuery.filter(q=>...);
}
let orderedQuery: OrderedQuery = postIndexQuery;
if (desc) {
orderedQuery = postIndexQuery.order("desc");
}
const results = await orderedQuery.collect();
Doogibo
DoogiboOP•4w ago
Thanks @lee , just to make sure I'm not missing anything... to remove all TS errors I had to do something like the following:
type RequestTableInfo = {
document: Doc<'requests'>;
fieldPaths: string;
indexes: {
by_caseNumber: ['caseNumber', '_creationTime'];
};
searchIndexes: {
search: {
searchField: 'searchText';
filterFields: never;
};
};
vectorIndexes: Record<string, never>;
};

const preIndexQuery = ctx.db.query('requests');
let postIndexQuery: Query<RequestTableInfo> = preIndexQuery;

if (true) {
postIndexQuery = preIndexQuery.withIndex('by_caseNumber', q =>
q.eq('caseNumber', 'blah')
);
}

if (true) {
postIndexQuery = postIndexQuery.filter(q =>
q.neq(q.field('status'), 'DRAFT')
);
}

let orderedQuery: OrderedQuery<RequestTableInfo> = postIndexQuery;

if (true) {
orderedQuery = postIndexQuery.order('desc');
}
type RequestTableInfo = {
document: Doc<'requests'>;
fieldPaths: string;
indexes: {
by_caseNumber: ['caseNumber', '_creationTime'];
};
searchIndexes: {
search: {
searchField: 'searchText';
filterFields: never;
};
};
vectorIndexes: Record<string, never>;
};

const preIndexQuery = ctx.db.query('requests');
let postIndexQuery: Query<RequestTableInfo> = preIndexQuery;

if (true) {
postIndexQuery = preIndexQuery.withIndex('by_caseNumber', q =>
q.eq('caseNumber', 'blah')
);
}

if (true) {
postIndexQuery = postIndexQuery.filter(q =>
q.neq(q.field('status'), 'DRAFT')
);
}

let orderedQuery: OrderedQuery<RequestTableInfo> = postIndexQuery;

if (true) {
orderedQuery = postIndexQuery.order('desc');
}
Have I missed a more convenient way to get this done? All good either way (when I didn't specify the search index, it complained... adding it solved it... even though I'm not using the search index in my query)!
edproton
edproton•4w ago
I duplicated this https://discord.com/channels/1019350475847499849/1312453606074749061 Is not very explicit, can you share some documentation? @lee
djbalin
djbalin•4w ago
I battled with something similar to this a few weeks ago as well. https://discord.com/channels/1019350475847499849/1282852743689535548/1301665342770249809 There's some discussion about it in this thread and a link to a lil' repo I made with my findings. Not done or thorough at all, but maybe some of its useful to you!
lee
lee•4w ago
This looks good to me. Are you still seeing problems?
edproton
edproton•3w ago
I'm checking this @djbalin, thanks.
Doogibo
DoogiboOP•3w ago
Thanks Lee and everyone else. It's fine for now. Could definitely be made nicer, but moving on for now. 🙂