@langchain/community
Version:
Third-party integrations for LangChain.js
155 lines (153 loc) • 5.69 kB
JavaScript
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const __langchain_core_documents = require_rolldown_runtime.__toESM(require("@langchain/core/documents"));
const __langchain_core_vectorstores = require_rolldown_runtime.__toESM(require("@langchain/core/vectorstores"));
const __lancedb_lancedb = require_rolldown_runtime.__toESM(require("@lancedb/lancedb"));
//#region src/vectorstores/lancedb.ts
var lancedb_exports = {};
require_rolldown_runtime.__export(lancedb_exports, { LanceDB: () => LanceDB });
/**
* A wrapper for an open-source database for vector-search with persistent
* storage. It simplifies retrieval, filtering, and management of
* embeddings.
*/
var LanceDB = class LanceDB extends __langchain_core_vectorstores.VectorStore {
table;
textKey;
uri;
tableName;
mode;
constructor(embeddings, args) {
super(embeddings, args || {});
this.table = args?.table;
this.embeddings = embeddings;
this.textKey = args?.textKey || "text";
this.uri = args?.uri || "~/lancedb";
this.tableName = args?.tableName || "langchain";
this.mode = args?.mode || "overwrite";
}
/**
* Adds documents to the database.
* @param documents The documents to be added.
* @returns A Promise that resolves when the documents have been added.
*/
async addDocuments(documents) {
const texts = documents.map(({ pageContent }) => pageContent);
return this.addVectors(await this.embeddings.embedDocuments(texts), documents);
}
_vectorstoreType() {
return "lancedb";
}
/**
* Adds vectors and their corresponding documents to the database.
* @param vectors The vectors to be added.
* @param documents The corresponding documents to be added.
* @returns A Promise that resolves when the vectors and documents have been added.
*/
async addVectors(vectors, documents) {
if (vectors.length === 0) return;
if (vectors.length !== documents.length) throw new Error(`Vectors and documents must have the same length`);
const data = [];
for (let i = 0; i < documents.length; i += 1) {
const record = {
vector: vectors[i],
[this.textKey]: documents[i].pageContent
};
Object.keys(documents[i].metadata).forEach((metaKey) => {
record[metaKey] = documents[i].metadata[metaKey];
});
data.push(record);
}
if (!this.table) {
const db = await (0, __lancedb_lancedb.connect)(this.uri);
this.table = await db.createTable(this.tableName, data, { mode: this.mode });
return;
}
await this.table.add(data);
}
/**
* Performs a similarity search in the database and returns
* the documents.
* @param query The query string.
* @param k The number of results to return.
* @returns A Promise that resolves with an array, each containing a Document.
*/
async similaritySearch(query, k) {
const results = await this.similaritySearchWithScore(query, k);
return results.map((result) => result[0]);
}
/**
* Performs a similarity search in the database and returns
* the documents and their scores.
* @param query The query string.
* @param k The number of results to return.
* @returns A Promise that resolves with an array of tuples, each containing a Document and its score.
*/
async similaritySearchWithScore(query, k) {
const queryEmbedding = await this.embeddings.embedQuery(query);
return this.similaritySearchVectorWithScore(queryEmbedding, k);
}
/**
* Performs a similarity search on the vectors in the database and returns
* the documents and their scores.
* @param query The query vector.
* @param k The number of results to return.
* @returns A Promise that resolves with an array of tuples, each containing a Document and its score.
*/
async similaritySearchVectorWithScore(query, k) {
if (!this.table) throw new Error("Table not found. Please add vectors to the table first.");
const results = await this.table.query().nearestTo(query).limit(k).toArray();
const docsAndScore = [];
results.forEach((item) => {
const metadata = {};
Object.keys(item).forEach((key) => {
if (key !== "vector" && key !== "score" && key !== this.textKey) metadata[key] = item[key];
});
docsAndScore.push([new __langchain_core_documents.Document({
pageContent: item[this.textKey],
metadata
}), item.score]);
});
return docsAndScore;
}
/**
* Creates a new instance of LanceDB from texts.
* @param texts The texts to be converted into documents.
* @param metadatas The metadata for the texts.
* @param embeddings The embeddings to be managed.
* @param dbConfig The configuration for the LanceDB instance.
* @returns A Promise that resolves with a new instance of LanceDB.
*/
static async fromTexts(texts, metadatas, embeddings, dbConfig) {
const docs = [];
for (let i = 0; i < texts.length; i += 1) {
const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas;
const newDoc = new __langchain_core_documents.Document({
pageContent: texts[i],
metadata
});
docs.push(newDoc);
}
return LanceDB.fromDocuments(docs, embeddings, dbConfig);
}
/**
* Creates a new instance of LanceDB from documents.
* @param docs The documents to be added to the database.
* @param embeddings The embeddings to be managed.
* @param dbConfig The configuration for the LanceDB instance.
* @returns A Promise that resolves with a new instance of LanceDB.
*/
static async fromDocuments(docs, embeddings, dbConfig) {
const instance = new this(embeddings, dbConfig);
await instance.addDocuments(docs);
return instance;
}
};
//#endregion
exports.LanceDB = LanceDB;
Object.defineProperty(exports, 'lancedb_exports', {
enumerable: true,
get: function () {
return lancedb_exports;
}
});
//# sourceMappingURL=lancedb.cjs.map