Loading...
Loading...
Learn how to enhance your CMS like PocketBase with AI-powered content recommendations using text embeddings, SQLite, and k-nearest neighbor search for efficient and scalable related content suggestions.
npx skill4agent add rodydavis/skills how-to-do-offline-recommendations-with-sqlite-and-geminiYou will need an API Key from AI Studio to generate the descriptions and embeddings.
We only need to generate a new embedding and description when the content changes which limits the billing costs to the frequency of the content changes.
.load ./vec0
create virtual table vec_examples using vec0(
sample_embedding float[8]
);
-- vectors can be provided as JSON or in a compact binary format
insert into vec_examples(rowid, sample_embedding)
values
(1, '[-0.200, 0.250, 0.341, -0.211, 0.645, 0.935, -0.316, -0.924]'),
(2, '[0.443, -0.501, 0.355, -0.771, 0.707, -0.708, -0.185, 0.362]'),
(3, '[0.716, -0.927, 0.134, 0.052, -0.669, 0.793, -0.634, -0.162]'),
(4, '[-0.710, 0.330, 0.656, 0.041, -0.990, 0.726, 0.385, -0.958]');
-- KNN style query
select
rowid,
distance
from vec_examples
where sample_embedding match '[0.890, 0.544, 0.825, 0.961, 0.358, 0.0196, 0.521, 0.175]'
order by distance
limit 2;
/*
┌───────┬──────────────────┐
│ rowid │ distance │
├───────┼──────────────────┤
│ 2 │ 2.38687372207642 │
│ 1 │ 2.38978505134583 │
└───────┴──────────────────┘
*/CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
content TEXT NOT NULL,
description TEXT.
embeddings TEXT
);
CREATE VIRTUAL TABLE vec_posts USING vec0(
id INTEGER PRIMARY KEY,
embedding float[768]
);
-- Sync vectors
INSERT INTO vec_posts(id, embedding) SELECT id, embeddings FROM posts;We could also setup triggers to keep them up to date but in PocketBase I am using event hooks to keep the virtual table udpated.
SELECT
vec_posts.id as id,
vec_posts.embedding as embedding,
posts.title as title,
posts.description as description,
posts.slug as slug
FROM vec_posts
INNER JOIN vec_posts.id = posts.id
WHERE embedding match ?
AND k = 6
ORDER BY distance;