glucinater
glucinater11mo ago

Advanced Filtering

Is there any way to filter with argument basic processing on the q.field() attribute? I am wary of using a searchIndex because I only want to return an item if it fits the criteria exactly. An example would be this:
const course = await ctx.db
.query("courses")
.filter((q) => q.and(
q.eq(q.field("Subject").toLowerCase(), args.Subject.toLowerCase()),
q.eq(q.field("Catalog"), args.Catalog)
)
).first();
const course = await ctx.db
.query("courses")
.filter((q) => q.and(
q.eq(q.field("Subject").toLowerCase(), args.Subject.toLowerCase()),
q.eq(q.field("Catalog"), args.Catalog)
)
).first();
3 Replies
jamwt
jamwt11mo ago
in this case, I would just iterate over the raw results and use something like _.filter or whatever. query.filter is just a JavaScript userspace process anyway. Unlike .withIndex, it's not utilizing some database-specific capability for optimization. so you can just write the loop yourself and do arbitrarily powerful comparisons since you're calling .first() you can just short-circuit and exit the loop when you find a matching record
lee
lee11mo ago
I don't think we have many examples in docs, so the syntax for filtering in javascript and exiting early would be:
let course = null;
for await (const doc of ctx.db.query("courses")) {
if (doc.Subject.toLowerCase() === args.Subject.toLowerCase() && doc.Catalog === args.Catalog) {
course = doc;
break;
}
}
let course = null;
for await (const doc of ctx.db.query("courses")) {
if (doc.Subject.toLowerCase() === args.Subject.toLowerCase() && doc.Catalog === args.Catalog) {
course = doc;
break;
}
}
ian
ian11mo ago
And to add one more option to the pile, I often see things like this stored as a second field with the lowercase version so you can do exact lookups. Eg storing the email as lowercase but a displayEmail with the casing the user provided

Did you find this page helpful?