#is it possible to search by prefix only?

1 messages · Page 1 of 1 (latest)

eager siren
#

I need to search exact matches that start with a code.
example search text : 13910
and expected results:

  • 13910-1
  • 13910-2

Currently it gives the first results plus a bunch of other results with fuzzy search.

In this case i would like to do a prefix search only.

I was thinking about using filter but not sure how to achieve startsWith with filter

#

the convex bot suggested to use the filter with q.gte("fieldname", "13910").lt("fieldname", "13910-10")

sudden dawn
#

Exactly what I was going to suggest, you’ll just want to tweak the specific strings a bit (assuming “-10” may not be the actual maximum value you want to use)

#

You’ll probably want to replace that second value with “13911”

eager siren
#

ok so i ended up with using search + filter

#
let existing = await db
        .query('quotes')
        .withSearchIndex('search_referenceCode', (q) =>
          q.search('referenceCode', referenceCode),
        )
        .filter((q) =>
          q.and(
            q.gte('referenceCode', referenceCode || ''),
            q.lt('referenceCode', referenceCode + '-10'),
          ),
        )
        .collect()
sudden dawn
#

Note that, given code 13910, 13910-10 and above would be excluded with that filter

eager siren
austere plank
#

Cool solution! I think a standard index would probably be a little faster. A regular index would allow more than 1024 results, and would put the codes in lexicographic order instead of relevance order. Maybe we should write up a pattern for using a regular index to search for a string prefix

eager siren
austere plank
#

It's basically what the convex bot said

index("referenceCode", ["referenceCode"]) in the schema

await db.query("quotes").withIndex("referenceCode", q=>q.gte("referenceCode", prefix).lte("referenceCode", prefix + "~")

Note "~" is pretty close to the end of the ascii table

eager siren
#

thanks, I'll try that too, good idea

#

I didnt know it's possible to use gte in index

#

btw I noticed I could not chain the .gte and .lte. I had to wrap them in an .and

austere plank
#

In a .filter you can't chain .gte with .lte, but in a .withIndex you should be able to. In a .withIndex there is no .and

sudden dawn
#

Totally missed that a filter was being used, should definitely be an index

eager siren
#

good to know

eager siren
sudden dawn
#

Right, just a regular index.