Spiced
Spiced13mo ago

Contains query on a collection

I want to have a contains query in a collection.
16 Replies
Spiced
SpicedOP13mo ago
@lee
lee
lee13mo ago
in your example, is the 'title' field a string or an array
Spiced
SpicedOP13mo ago
string
export const getDiagrams = query({
args: {
searchQ: v.optional(v.string()),
},
handler: async (ctx, args) => {
args.searchQ = "Diagr";

const identity = await ctx.auth.getUserIdentity();

if (!identity) {
throw new Error("Unauthorized");
}
const userId = identity.subject;

const dashboard = (
await ctx.db
.query("diagrams")
.withIndex("by_user", (q) => q.eq("userId", userId))
.filter((q) => q.eq(q.field("isArchived"), false))
.collect()
).filter((diagram) =>
args.searchQ != null || args.searchQ != undefined
? diagram.title.includes(args.searchQ)
: true,
);

return dashboard;
},
});
export const getDiagrams = query({
args: {
searchQ: v.optional(v.string()),
},
handler: async (ctx, args) => {
args.searchQ = "Diagr";

const identity = await ctx.auth.getUserIdentity();

if (!identity) {
throw new Error("Unauthorized");
}
const userId = identity.subject;

const dashboard = (
await ctx.db
.query("diagrams")
.withIndex("by_user", (q) => q.eq("userId", userId))
.filter((q) => q.eq(q.field("isArchived"), false))
.collect()
).filter((diagram) =>
args.searchQ != null || args.searchQ != undefined
? diagram.title.includes(args.searchQ)
: true,
);

return dashboard;
},
});
lee
lee13mo ago
sounds like you want a full text search index https://docs.convex.dev/text-search
Full Text Search | Convex Developer Hub
Run search queries over your Convex documents
Spiced
SpicedOP13mo ago
This is the query, when i do have a searchQ, i want to just query based on if the name contains the needed search First issue is: A name. Must be unique per table. What if i have the same name for files owned by different users ? Would that cause an issue ? OHHH, Nevermind, thats the column name Am i correct ?
lee
lee13mo ago
A name. Must be unique per table.
is referring to the name of the search index, which is a single string configured in your schema.ts in the example in the docs, the name is "search_body"
Spiced
SpicedOP13mo ago
const dashboard = await ctx.db
.query("diagrams")
.withIndex("by_user", (q) => q.eq("userId", userId))

.withSearchIndex("search_diagram_name", (q) =>
q.search("title", args.searchQ ? args.searchQ : ""),
)
.filter((q) => q.eq(q.field("isArchived"), false))

.collect();
const dashboard = await ctx.db
.query("diagrams")
.withIndex("by_user", (q) => q.eq("userId", userId))

.withSearchIndex("search_diagram_name", (q) =>
q.search("title", args.searchQ ? args.searchQ : ""),
)
.filter((q) => q.eq(q.field("isArchived"), false))

.collect();
Okay so in the updated code, i dont think i can use withIndex and withSearchIndex
lee
lee13mo ago
you can only use one index at a time yeah. you can make userId a filter field on the search index btw since you asked about whether js filters are slow, this may be of interest: https://discord.com/channels/1019350475847499849/1195755890838622359
Spiced
SpicedOP13mo ago
const dashboard = await ctx.db
.query("diagrams")
.withSearchIndex("search_diagram_name", (q) =>
q
.search("title", args.searchQ ? args.searchQ : "")
.eq("userId", userId),
)
.filter((q) => q.eq(q.field("isArchived"), false))

.collect();
const dashboard = await ctx.db
.query("diagrams")
.withSearchIndex("search_diagram_name", (q) =>
q
.search("title", args.searchQ ? args.searchQ : "")
.eq("userId", userId),
)
.filter((q) => q.eq(q.field("isArchived"), false))

.collect();
Hmm it seems im getting an error here Argument of type 'string' is not assignable to parameter of type 'never'. on userId OHH I have to add it to the filter fields, wow Okay that was tough to wrap my head around, does it mean i have to keep the index for the userId if i want to use it seperately ?
lee
lee13mo ago
yep if you want to query just by user id i would keep the index on that. you can add isArchived as another filter field if you want
Spiced
SpicedOP13mo ago
export const getDiagrams = query({
args: {
searchQ: v.optional(v.string()),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();

if (!identity) {
throw new Error("Unauthorized");
}
const userId = identity.subject;

const dashboard = await ctx.db
.query("diagrams")
.withSearchIndex("search_diagram_name", (q) =>
q
.search("title", args.searchQ ? args.searchQ : "")
.eq("userId", userId),
)
.filter((q) => q.eq(q.field("isArchived"), false))

.collect();

return dashboard;
},
});
export const getDiagrams = query({
args: {
searchQ: v.optional(v.string()),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();

if (!identity) {
throw new Error("Unauthorized");
}
const userId = identity.subject;

const dashboard = await ctx.db
.query("diagrams")
.withSearchIndex("search_diagram_name", (q) =>
q
.search("title", args.searchQ ? args.searchQ : "")
.eq("userId", userId),
)
.filter((q) => q.eq(q.field("isArchived"), false))

.collect();

return dashboard;
},
});
Also one more question, how can i make it when args.searchQ is not defined, i just return everything ?
lee
lee13mo ago
if you want to return everything, you can't use a search index for that, so something like
if (args.searchQ) {
dashboard = ctx.db.query("diagrams").withSearchIndex("search_diagram_name", q=>q.search("title", args.searchQ).eq("userId", userId).take(10);
} else {
dashboard = ctx.db.query("diagrams").withIndex("by_user", q=>q.eq("userId", userId)).take(10);
}
if (args.searchQ) {
dashboard = ctx.db.query("diagrams").withSearchIndex("search_diagram_name", q=>q.search("title", args.searchQ).eq("userId", userId).take(10);
} else {
dashboard = ctx.db.query("diagrams").withIndex("by_user", q=>q.eq("userId", userId)).take(10);
}
Spiced
SpicedOP13mo ago
Ahh i see i have to have an if else statememt Oh wait, just a question, once i collect the data, i cannot run a query on them can i ?
lee
lee13mo ago
i'm not sure what you mean by "run a query on them" you can manipulate the documents however you want in javascript
Spiced
SpicedOP13mo ago
Oh wait nvm, im trying to put my .net sql logic in here Thank you so much for your help! I really appreciate it
lee
lee13mo ago
happy to help. Reach out again if u have questions

Did you find this page helpful?