ian
ian12mo ago

How to search by multiple fields?

@ckobasti writes: I want a search for people feature in my app, so my question is what is best method to search within single table by any parameter (not really any but username, firstName, lastName, etc.. something like instagram search)? I mean by multiple parameters
12 Replies
ian
ianOP12mo ago
To search across multiple fields in one search, I would do this: 1. Make a new field that combines a few fields:
ctx.db.insert("users", {
firstName,
lastName,
username,
role,
mySearchField: `${firstName} ${lastName} @${username} role:${role} ...`.
});
ctx.db.insert("users", {
firstName,
lastName,
username,
role,
mySearchField: `${firstName} ${lastName} @${username} role:${role} ...`.
});
It'd start out as v.optional(v.string()) 2. Add a function to write / update a user record, that computes this field whenever you're writing or updating the fields. 3. Use that field to search over 4. Run a backfill migration to populate that field for existing users 5. Change the field type to v.string() to ensure you don't add a user without it going forward (and get better type errors)
ckobasti
ckobasti12mo ago
Uh im overreading this 20 times and still cant get it haha So every user row in table should have new field 'mySearchField', and store next few users in that field?
Indy
Indy12mo ago
So you basically create a new field that contains the content of the fields from that row you want to search and manually keep it up to date. Convex doesn't support multifiled search out of the box, so this is essentially a workaround.
ckobasti
ckobasti12mo ago
Ooohhhh yeah i got it now But how do i search within that field Oh basically im making string full of all user's properties and then just doing full text search? over that field
Indy
Indy12mo ago
Yep
ckobasti
ckobasti12mo ago
bombastic thanks I did it Just one more little feature on feature.. export const searchForPeople = query({ args: { id: v.id("user"), query: v.string(), }, handler: async (ctx, args) => { const user = await ctx.db.get(args.id); if (!user) { throw new Error("Unauthenticated."); } const people = await ctx.db .query("user") .withSearchIndex("search_people", (q) => q.search("mySearchField", args.query) ) .take(5); return people; }, }); This is my function that searches by Words Is it possible to make it search by connected letters So i dont have to type whole word to search it
ian
ianOP12mo ago
With convex 1.7 it will do prefix and fuzzy search The last search term will search for a prefix, and it will also return results that have up to 2 errors (missing / incorrect characters) btw that authentication code seems a little sus - it relies on user ID to be a secret. Happy to chat in another thread about auth strategies
ckobasti
ckobasti12mo ago
Nevermind word search is okay for now now i wanna send friend requests, and i figured it out how to do it.. but on the other side i want live preview of whats happening in my database
ian
ianOP12mo ago
let's start another thread for that discussion - but I'm signing off for today
ckobasti
ckobasti12mo ago
something like websocket Thanks appreciate for the help! Have a gn
Tarik
Tarik6mo ago
@ian Hey man. Is this still the best approach or did you guys manage to add searching across multiple fields out of the box?
ian
ianOP6mo ago
Searching across multiple fields still requires multiple queries, denormalizing is still workable, so yes this is still the recommendation