Skip to content

Instantly share code, notes, and snippets.

@kuc-arc-f
Created January 9, 2026 23:11
Show Gist options
  • Select an option

  • Save kuc-arc-f/6113c398b9e79dc6b534c35e13035447 to your computer and use it in GitHub Desktop.

Select an option

Save kuc-arc-f/6113c398b9e79dc6b534c35e13035447 to your computer and use it in GitHub Desktop.
DuckDB , node example
import duckdb from "duckdb";
// DB作成
const db = new duckdb.Database("vector.db");
const conn = db.connect();
// ベクトル拡張機能をインストール・ロード
// 注意: インターネット接続が必要な場合があります。
// 環境によっては 'INSTALL vss' が失敗することがあります。(オフライン環境など)
conn.all(`INSTALL vss; LOAD vss;`, (err) => {
if (err) {
console.warn('警告: 拡張機能のロードエラー:', err.message);
console.warn('VSS拡張機能なしで続行します。FLOAT[N]型はDuckDBの基本機能として使用可能です。');
// エラーでも続行する形に変更 (VSSは検索用で、テーブル作成だけならCore機能でいける場合があるため)
} else {
console.log('✓ VSS拡張機能をロードしました');
}
// テーブル作成
createTable();
});
function createTable() {
// VECTOR型ではなく FLOAT[3] (固定長リスト) を使用
const createTableSQL = `
CREATE TABLE IF NOT EXISTS embeddings (
id INTEGER PRIMARY KEY,
text VARCHAR,
vector FLOAT[3]
);
`;
//-- 3次元ベクトルの例
conn.run(createTableSQL, (err) => {
if (err) {
console.error('テーブル作成エラー:', err);
return;
}
console.log('✓ テーブルを作成しました');
// データ挿入
insertData();
});
}
function insertData() {
// ベクトルは明示的にキャストするか、ドライバが配列を正しく認識できるようにする
// バージョンによってはJS配列がそのまま渡らない場合があるため、CASTを利用すると安全な場合がある
// また、配列がうまく渡らない場合は `JSON.stringify` や 文字列 `[0.1, 0.2, 0.3]` で渡す必要があるかもしれない
const stmt = conn.prepare("INSERT INTO embeddings (id, text, vector) VALUES (?, ?, CAST(? AS FLOAT[3]))");
const data = [
{ id: 1, text: 'Apple', vector: [0.1, 0.2, 0.3] },
{ id: 2, text: 'Banana', vector: [0.4, 0.5, 0.6] },
{ id: 3, text: 'Orange', vector: [0.7, 0.8, 0.9] }
];
let pending = data.length;
if (pending === 0) return;
console.log('データ挿入開始...');
data.forEach((row) => {
// JS配列をDuckDBのリストリテラル文字列形式に変換して渡す
// Array bindingがうまくいかない環境のためのワークアラウンド
const vectorStr = `[${row.vector.join(', ')}]`;
stmt.run(row.id, row.text, vectorStr, (err) => {
if (err) {
// 重複エラーなどはここでキャッチ
console.error(`データ挿入エラー (ID: ${row.id}):`, err.message);
} else {
console.log(`✓ データ挿入成功: ${row.text}`);
}
pending--;
if (pending === 0) {
stmt.finalize();
console.log('全データの挿入処理が完了しました。');
// 登録データの確認
verifyData();
}
});
});
}
function verifyData() {
console.log('\n--- 登録データの確認 ---');
conn.all("SELECT * FROM embeddings", (err, rows) => {
if (err) {
console.error('データ取得エラー:', err);
} else {
console.table(rows);
}
// 非同期処理が残っていなければプロセスは終了するはずですが、明示的に閉じたい場合:
// conn.disconnect(); // duckdb node apiによっては close() かもしれないが、通常はGC任せか明示的close
});
}
{
"name": "dock_1",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"duckdb": "^1.4.3"
}
}
import duckdb from "duckdb";
// DB作成
const db = new duckdb.Database("vector.db");
const conn = db.connect();
// ベクトル拡張機能をインストール・ロード
// 注意: インターネット接続が必要な場合があります。
// 環境によっては 'INSTALL vss' が失敗することがあります。(オフライン環境など)
conn.all(`INSTALL vss; LOAD vss;`, (err) => {
if (err) {
console.warn('警告: 拡張機能のロードエラー:', err.message);
console.warn('VSS拡張機能なしで続行します。FLOAT[N]型はDuckDBの基本機能として使用可能です。');
// エラーでも続行する形に変更 (VSSは検索用で、テーブル作成だけならCore機能でいける場合があるため)
} else {
console.log('✓ VSS拡張機能をロードしました');
}
// テーブル作成
createTable();
});
function createTable() {
// VECTOR型ではなく FLOAT[3] (固定長リスト) を使用
const createTableSQL = `
CREATE TABLE IF NOT EXISTS embeddings (
id INTEGER PRIMARY KEY,
text VARCHAR,
vector FLOAT[3]
);
`;
//-- 3次元ベクトルの例
conn.run(createTableSQL, (err) => {
if (err) {
console.error('テーブル作成エラー:', err);
return;
}
console.log('✓ テーブルを作成しました');
// データ挿入
searchData();
});
}
function searchData() {
console.log('\n--- ベクトル検索の実行 ---');
// 検索用ベクトル (例: Appleに近いベクトル)
const queryVector = [0.12, 0.22, 0.32];
//const queryVector = [0.4, 0.5, 0.6];
console.log('検索クエリベクトル:', queryVector);
// コサイン類似度で検索 (近い順)
// vss拡張機能の array_cosine_similarity を使用
// 距離関数を使う場合は array_distance (ユークリッド距離) など
const searchSQL = `
SELECT
id,
text,
vector,
array_cosine_similarity(vector, CAST(? AS FLOAT[3])) AS similarity
FROM embeddings
ORDER BY similarity DESC
LIMIT 2;
`;
// パラメータバインディング用に文字列化: "[0.12, 0.22, 0.32]"
const vectorStr = `[${queryVector.join(', ')}]`;
conn.all(searchSQL, vectorStr, (err, rows) => {
if (err) {
console.error('検索エラー:', err);
} else {
console.log('検索結果 (類似度順):');
console.table(rows);
}
// 処理終了
// conn.disconnect(); // 必要に応じて
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment