CabalDAO
CabalDAO7mo ago

optional search

I tried like this:
let facilities = ctx.db
.query("facility")
.filter(q => args.id ? q.eq(q.field("_id"), args.id) : true);

if (args.name) {
facilities = facilities.withSearchIndex("name", q => q.search("name", args.name!));
}
let facilities = ctx.db
.query("facility")
.filter(q => args.id ? q.eq(q.field("_id"), args.id) : true);

if (args.name) {
facilities = facilities.withSearchIndex("name", q => q.search("name", args.name!));
}
But it doesn't let me do that
4 Replies
lee
lee7mo ago
try this
let facilities = ctx.db
.query("facility");

if (args.name) {
facilities = facilities.withSearchIndex("name", q => q.search("name", args.name!));
}

facilities = facilities.filter(q => args.id ? q.eq(q.field("_id"), args.id) : true);
let facilities = ctx.db
.query("facility");

if (args.name) {
facilities = facilities.withSearchIndex("name", q => q.search("name", args.name!));
}

facilities = facilities.filter(q => args.id ? q.eq(q.field("_id"), args.id) : true);
CabalDAO
CabalDAOOP7mo ago
wouldn't it be faster to filter by id first? But also when I try what you wrote, I get a typescript error at facilities = facilities It is also telling me that .withSearchIndex is not a function - but my schema has it
export default defineSchema({
facility: defineTable({
address: v.object({
city: v.string(),
state: v.string(),
street: v.string(),
zip: v.string(),
}),
columns: v.array(
v.object({
id: v.string(),
label: v.string(),
sorting: v.object({
green: v.float64(),
red: v.float64(),
yellow: v.float64(),
}),
})
),
email: v.string(),
name: v.string(),
phone: v.string(),
}).searchIndex("name", { searchField: "name" }),
...
export default defineSchema({
facility: defineTable({
address: v.object({
city: v.string(),
state: v.string(),
street: v.string(),
zip: v.string(),
}),
columns: v.array(
v.object({
id: v.string(),
label: v.string(),
sorting: v.object({
green: v.float64(),
red: v.float64(),
yellow: v.float64(),
}),
})
),
email: v.string(),
name: v.string(),
phone: v.string(),
}).searchIndex("name", { searchField: "name" }),
...
Oh i guess I can't do a withSearchIndex after a filter... strange
lee
lee7mo ago
typescript might not be happy with this since the types differ. personally i would split the cases more
let facilities;
if (args.id) {
facilities = [await ctx.db.get(id)].filter((f) => !args.name || f.name.contains(args.name));
} else if (args.name) {
facilities = await ctx.db.query("facility").withSearchIndex("name", q => q.search("name", args.name!)).collect();
} else {
facilities = await ctx.db.query("facility").collect();
}
let facilities;
if (args.id) {
facilities = [await ctx.db.get(id)].filter((f) => !args.name || f.name.contains(args.name));
} else if (args.name) {
facilities = await ctx.db.query("facility").withSearchIndex("name", q => q.search("name", args.name!)).collect();
} else {
facilities = await ctx.db.query("facility").collect();
}
CabalDAO
CabalDAOOP7mo ago
Ok thank you - strange though, would be nice if we can keep the same var throughout... i ended up doing this and it worked ok - typescript only had an issue re-assigning it to the same var if it was .withSearchIndex but re-assigning with adding just .filter seemed to work just fine
let preQuery = ctx.db
.query("facility");

let facilities;

if (args.name) {
facilities = preQuery
.withSearchIndex("name", q => q.search("name", args.name!));
} else {
facilities = preQuery;
}

facilities = facilities
.filter(q => args.id ? q.eq(q.field("_id"), args.id) : true);

return await facilities.collect();
let preQuery = ctx.db
.query("facility");

let facilities;

if (args.name) {
facilities = preQuery
.withSearchIndex("name", q => q.search("name", args.name!));
} else {
facilities = preQuery;
}

facilities = facilities
.filter(q => args.id ? q.eq(q.field("_id"), args.id) : true);

return await facilities.collect();

Did you find this page helpful?