-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathindex.mjs
110 lines (95 loc) · 3.24 KB
/
index.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import { createClient } from "@libsql/client";
import ollama from "ollama";
const client = createClient({
url: "file:local.db",
});
await client.batch(
[
"CREATE TABLE IF NOT EXISTS movies (id INTEGER PRIMARY KEY, title TEXT NOT NULL, description TEXT NOT NULL, embedding F32_BLOB(4096))",
"CREATE INDEX IF NOT EXISTS movies_embedding_idx ON movies(libsql_vector_idx(embedding))",
],
"write",
);
async function getEmbedding(prompt) {
const response = await ollama.embeddings({
model: "mistral",
prompt,
});
return response.embedding;
}
async function insertMovie(id, title, description) {
const embedding = await getEmbedding(description);
await client.execute({
sql: `INSERT OR REPLACE INTO movies (id, title, description, embedding) VALUES (?, ?, ?, vector(?))`,
args: [id, title, description, JSON.stringify(embedding)],
});
}
async function insertMovieIfNotExists(id, title, description) {
const existing = await client.execute({
sql: "SELECT id FROM movies WHERE id = ?",
args: [id],
});
if (existing.rows.length === 0) {
await insertMovie(id, title, description);
console.log(`Inserted: ${title} (ID: ${id})`);
} else {
console.log(`Movie already exists: ${title} (ID: ${id})`);
}
}
async function findSimilarMovies(description, limit = 3) {
const queryEmbedding = await getEmbedding(description);
const results = await client.execute({
sql: `
WITH vector_scores AS (
SELECT DISTINCT
id,
title,
description,
1 - vector_distance_cos(embedding, vector32(?)) AS similarity
FROM movies
ORDER BY similarity DESC
LIMIT ?
)
SELECT id, title, description, similarity FROM vector_scores
`,
args: [JSON.stringify(queryEmbedding), limit],
});
return results.rows;
}
try {
const sampleMovies = [
{
id: 1,
title: "Inception",
description:
"A thief who enters the dreams of others to steal secrets from their subconscious.",
},
{
id: 2,
title: "The Matrix",
description:
"A computer programmer discovers that reality as he knows it is a simulation created by machines.",
},
{
id: 3,
title: "Interstellar",
description:
"Astronauts travel through a wormhole in search of a new habitable planet for humanity.",
},
];
for (const movie of sampleMovies) {
await insertMovieIfNotExists(movie.id, movie.title, movie.description);
}
const query =
"A sci-fi movie about virtual reality and artificial intelligence";
console.log("\nSearching for movies similar to:", query);
const similarMovies = await findSimilarMovies(query);
console.log("\nSimilar movies found:");
similarMovies.forEach((movie) => {
console.log(`\nTitle: ${movie.title}`);
console.log(`Description: ${movie.description}`);
console.log(`Similarity: ${movie.similarity.toFixed(4)}`);
});
} catch (error) {
console.error("Error:", error);
}