Ranking Favorite Food Records in Database Search Results

TLDR Julian asked for best practices to rank favorite food records in search results. John suggested using _eval. Jason recommended adding a favorited_by_user_ids array field to each record.

Powered by Struct AI
Join the chat
Jun 20, 2023 (3 months ago)
Photo of md5-309edd752adeb3e0ea515a8c8165ce45
01:59 PM
Scenario pitch: I have a db of food records. Users can mark single records as favorites. The favorite state should be considered on the search ranking.

Example: User searches for "cream". The desired outcome would be:
1. "Heavy Cream (14% fat)" (<--- marked as favorite)
2. "Cream"
3. "Best cream"

Token position is relevant (2 matches before 3) and records marked as favorite should be on top if at least matched partially (prefix or infix).

Any ideas for best practices to achieve this? 🙏
Photo of md5-21545f1facb7836c149bc4c70752bd2b
03:20 PM
One way of accomplishing this is by using _eval. I created a collection with
    {"title": "Heavy Cream", "product_id": "1"},
    {"title": "Cream", "product_id": "2"},
    {"title": "Best Cream", "product_id": "3"},
    {"title": "Wow I love this cream", "product_id": "4"},

which normally would give
Wow I love this cream
Best Cream
Heavy Cream

for "cream", but if you set
"sort_by": "_eval(product_id:[1,4]):desc,_text_match:desc"

you get
Wow I love this cream <- favorite
Heavy Cream <- favorite
Best Cream

There could be some performance costs if the user has a lot of favorites, but in my experience with large filters it hasn't been a problem even with many hundreds of items.

Note that this can result in worse matches marked as favorite coming before better matches, but I don't think it'll be much of a problem in practice (most of the time the entire candidate set will be quite good)
Photo of md5-309edd752adeb3e0ea515a8c8165ce45
03:58 PM
Nice, I will give this a try. Thank you, appreciated!
Photo of md5-8813087cccc512313602b6d9f9ece19f
04:11 PM
Nice, that’s a great use of optional filtering John! Thank you for sharing.
04:13 PM
Extending on your idea, another thing that could be done is adding an array field called say favorited_by_user_ids to each record, and store which users have favorited each product.

Then you could do something like this:

"sort_by": "_eval(favorited_by_user_ids:=<CURRENT_USERS_ID>):desc,_text_match:desc"
04:14 PM
This way you don’t have to query your DB to get the list of user favorites, and can keep the search fully isolated to just Typesense