@orama/orama
Version:
A complete search engine and RAG pipeline in your browser, server, or edge network with support for full-text, vector, and hybrid search in less than 2kb.
101 lines • 4.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.innerVectorSearch = innerVectorSearch;
exports.searchVector = searchVector;
const utils_js_1 = require("../utils.js");
const facets_js_1 = require("../components/facets.js");
const errors_js_1 = require("../errors.js");
const groups_js_1 = require("../components/groups.js");
const internal_document_id_store_js_1 = require("../components/internal-document-id-store.js");
const hooks_js_1 = require("../components/hooks.js");
const vector_js_1 = require("../trees/vector.js");
function innerVectorSearch(orama, params, language) {
const vector = params.vector;
if (vector && (!('value' in vector) || !('property' in vector))) {
throw (0, errors_js_1.createError)('INVALID_VECTOR_INPUT', Object.keys(vector).join(', '));
}
const vectorIndex = orama.data.index.vectorIndexes[vector.property];
const vectorSize = vectorIndex.node.size;
if (vector?.value.length !== vectorSize) {
if (vector?.property === undefined || vector?.value.length === undefined) {
throw (0, errors_js_1.createError)('INVALID_INPUT_VECTOR', 'undefined', vectorSize, 'undefined');
}
throw (0, errors_js_1.createError)('INVALID_INPUT_VECTOR', vector.property, vectorSize, vector.value.length);
}
const index = orama.data.index;
let whereFiltersIDs;
const hasFilters = Object.keys(params.where ?? {}).length > 0;
if (hasFilters) {
whereFiltersIDs = orama.index.searchByWhereClause(index, orama.tokenizer, params.where, language);
}
return vectorIndex.node.find(vector.value, params.similarity ?? vector_js_1.DEFAULT_SIMILARITY, whereFiltersIDs);
}
function searchVector(orama, params, language = 'english') {
const timeStart = (0, utils_js_1.getNanosecondsTime)();
function performSearchLogic() {
const results = innerVectorSearch(orama, params, language)
.sort(utils_js_1.sortTokenScorePredicate);
let facetsResults = [];
const shouldCalculateFacets = params.facets && Object.keys(params.facets).length > 0;
if (shouldCalculateFacets) {
const facets = (0, facets_js_1.getFacets)(orama, results, params.facets);
facetsResults = facets;
}
const vectorProperty = params.vector.property;
const includeVectors = params.includeVectors ?? false;
const limit = params.limit ?? 10;
const offset = params.offset ?? 0;
const docs = Array.from({ length: limit });
for (let i = 0; i < limit; i++) {
const result = results[i + offset];
if (!result) {
break;
}
const doc = orama.data.docs.docs[result[0]];
if (doc) {
if (!includeVectors) {
doc[vectorProperty] = null;
}
const newDoc = {
id: (0, internal_document_id_store_js_1.getDocumentIdFromInternalId)(orama.internalDocumentIDStore, result[0]),
score: result[1],
document: doc
};
docs[i] = newDoc;
}
}
let groups = [];
if (params.groupBy) {
groups = (0, groups_js_1.getGroups)(orama, results, params.groupBy);
}
const timeEnd = (0, utils_js_1.getNanosecondsTime)();
const elapsedTime = timeEnd - timeStart;
return {
count: results.length,
hits: docs.filter(Boolean),
elapsed: {
raw: Number(elapsedTime),
formatted: (0, utils_js_1.formatNanoseconds)(elapsedTime)
},
...(facetsResults ? { facets: facetsResults } : {}),
...(groups ? { groups } : {})
};
}
async function executeSearchAsync() {
if (orama.beforeSearch) {
await (0, hooks_js_1.runBeforeSearch)(orama.beforeSearch, orama, params, language);
}
const results = performSearchLogic();
if (orama.afterSearch) {
await (0, hooks_js_1.runAfterSearch)(orama.afterSearch, orama, params, language, results);
}
return results;
}
const asyncNeeded = orama.beforeSearch?.length || orama.afterSearch?.length;
if (asyncNeeded) {
return executeSearchAsync();
}
// Sync path
return performSearchLogic();
}
//# sourceMappingURL=search-vector.js.map