@orama/orama
Advanced tools
Comparing version 2.0.22 to 2.0.23
import type { AnyIndexStore, AnyOrama, IIndex, SearchableType, SearchableValue, SearchContext, SearchParamsFullText, Tokenizer, TokenScore, TypedDocument, VectorIndex, WhereCondition } from '../types.js'; | ||
import type { InsertOptions } from '../methods/insert.js'; | ||
import { RootNode as AVLRootNode } from '../trees/avl.js'; | ||
@@ -42,3 +43,3 @@ import { FlatTree } from '../trees/flat.js'; | ||
export declare function create<T extends AnyOrama, TSchema extends T['schema']>(orama: T, sharedInternalDocumentStore: T['internalDocumentIDStore'], schema: TSchema, index?: Index, prefix?: string): Promise<Index>; | ||
export declare function insert(implementation: IIndex<Index>, index: Index, prop: string, id: DocumentID, value: SearchableValue, schemaType: SearchableType, language: string | undefined, tokenizer: Tokenizer, docsCount: number): Promise<void>; | ||
export declare function insert(implementation: IIndex<Index>, index: Index, prop: string, id: DocumentID, value: SearchableValue, schemaType: SearchableType, language: string | undefined, tokenizer: Tokenizer, docsCount: number, options?: InsertOptions): Promise<void>; | ||
export declare function remove(implementation: IIndex<Index>, index: Index, prop: string, id: DocumentID, value: SearchableValue, schemaType: SearchableType, language: string | undefined, tokenizer: Tokenizer, docsCount: number): Promise<boolean>; | ||
@@ -45,0 +46,0 @@ export declare function search<T extends AnyOrama, ResultDocument = TypedDocument<T>>(context: SearchContext<T, ResultDocument, SearchParamsFullText<T, ResultDocument>>, index: Index, prop: string, term: string): Promise<TokenScore[]>; |
@@ -152,3 +152,3 @@ import { createError } from '../errors.js'; | ||
} | ||
function insertScalarBuilder(implementation, index, prop, id, language, tokenizer, docsCount) { | ||
function insertScalarBuilder(implementation, index, prop, id, language, tokenizer, docsCount, options) { | ||
return async (value)=>{ | ||
@@ -165,5 +165,6 @@ const internalId = getInternalDocumentId(index.sharedInternalDocumentStore, id); | ||
{ | ||
const avlRebalanceThreshold = (options === null || options === void 0 ? void 0 : options.avlRebalanceThreshold) ?? 1; | ||
avlInsert(node, value, [ | ||
internalId | ||
]); | ||
], avlRebalanceThreshold); | ||
break; | ||
@@ -196,7 +197,7 @@ } | ||
} | ||
export async function insert(implementation, index, prop, id, value, schemaType, language, tokenizer, docsCount) { | ||
export async function insert(implementation, index, prop, id, value, schemaType, language, tokenizer, docsCount, options) { | ||
if (isVectorType(schemaType)) { | ||
return insertVector(index, prop, value, id); | ||
} | ||
const insertScalar = insertScalarBuilder(implementation, index, prop, id, language, tokenizer, docsCount); | ||
const insertScalar = insertScalarBuilder(implementation, index, prop, id, language, tokenizer, docsCount, options); | ||
if (!isArrayType(schemaType)) { | ||
@@ -203,0 +204,0 @@ return insertScalar(value); |
@@ -117,5 +117,5 @@ import { formatElapsedTime, getDocumentIndexId, getDocumentProperties, validateSchema } from '../components/defaults.js'; | ||
function getVersion() { | ||
return '2.0.22'; | ||
return '2.0.23'; | ||
} | ||
//# sourceMappingURL=create.js.map |
import { AnyOrama, PartialSchemaDeep, TypedDocument } from '../types.js'; | ||
export declare function insert<T extends AnyOrama>(orama: T, doc: PartialSchemaDeep<TypedDocument<T>>, language?: string, skipHooks?: boolean): Promise<string>; | ||
export type InsertOptions = { | ||
avlRebalanceThreshold?: number; | ||
}; | ||
export declare function insert<T extends AnyOrama>(orama: T, doc: PartialSchemaDeep<TypedDocument<T>>, language?: string, skipHooks?: boolean, options?: InsertOptions): Promise<string>; | ||
export declare function insertMultiple<T extends AnyOrama>(orama: T, docs: PartialSchemaDeep<TypedDocument<T>>[], batchSize?: number, language?: string, skipHooks?: boolean, timeout?: number): Promise<string[]>; | ||
export declare function innerInsertMultiple<T extends AnyOrama>(orama: T, docs: PartialSchemaDeep<TypedDocument<T>>[], batchSize?: number, language?: string, skipHooks?: boolean, timeout?: number): Promise<string[]>; |
@@ -5,3 +5,3 @@ import { isArrayType, isGeoPointType, isVectorType } from '../components.js'; | ||
import { createError } from '../errors.js'; | ||
export async function insert(orama, doc, language, skipHooks) { | ||
export async function insert(orama, doc, language, skipHooks, options) { | ||
const errorProperty = await orama.validateSchema(doc, orama.schema); | ||
@@ -11,3 +11,3 @@ if (errorProperty) { | ||
} | ||
return innerInsert(orama, doc, language, skipHooks); | ||
return innerInsert(orama, doc, language, skipHooks, options); | ||
} | ||
@@ -22,3 +22,3 @@ const ENUM_TYPE = new Set([ | ||
]); | ||
async function innerInsert(orama, doc, language, skipHooks) { | ||
async function innerInsert(orama, doc, language, skipHooks, options) { | ||
const { index , docs } = orama.data; | ||
@@ -69,3 +69,3 @@ const id = await orama.getDocumentIndexId(doc); | ||
await ((_orama_index_beforeInsert = (_orama_index = orama.index).beforeInsert) === null || _orama_index_beforeInsert === void 0 ? void 0 : _orama_index_beforeInsert.call(_orama_index, orama.data.index, prop, id, value, expectedType, language, orama.tokenizer, docsCount)); | ||
await orama.index.insert(orama.index, orama.data.index, prop, id, value, expectedType, language, orama.tokenizer, docsCount); | ||
await orama.index.insert(orama.index, orama.data.index, prop, id, value, expectedType, language, orama.tokenizer, docsCount, options); | ||
await ((_orama_index_afterInsert = (_orama_index1 = orama.index).afterInsert) === null || _orama_index_afterInsert === void 0 ? void 0 : _orama_index_afterInsert.call(_orama_index1, orama.data.index, prop, id, value, expectedType, language, orama.tokenizer, docsCount)); | ||
@@ -120,3 +120,6 @@ } | ||
try { | ||
const id = await insert(orama, doc, language, skipHooks); | ||
const options = { | ||
avlRebalanceThreshold: batch.length | ||
}; | ||
const id = await insert(orama, doc, language, skipHooks, options); | ||
ids.push(id); | ||
@@ -123,0 +126,0 @@ } catch (err) { |
@@ -19,5 +19,5 @@ import { Nullable } from '../types.js'; | ||
export declare function create<K, V>(key: K, value: V): RootNode<K, V>; | ||
export declare function insert<K, V>(rootNode: RootNode<K, V[]>, key: K, newValue: V[]): void; | ||
export declare function insert<K, V>(rootNode: RootNode<K, V[]>, key: K, newValue: V[], rebalanceThreshold?: number): void; | ||
export declare function find<K, V>(root: RootNode<K, V>, key: K): Nullable<V>; | ||
export declare function remove<K, V>(rootNode: Nullable<RootNode<K, V>>, key: K): void; | ||
export declare function removeDocument<K, V>(root: RootNode<K, V[]>, id: V, key: K): void; |
@@ -149,5 +149,7 @@ import { safeArrayPush } from '../utils.js'; | ||
} | ||
export function insert(rootNode, key, newValue) { | ||
let insertCount = 0; | ||
export function insert(rootNode, key, newValue, rebalanceThreshold = 500) { | ||
function insertNode(node, key, newValue) { | ||
if (node === null) { | ||
insertCount++; | ||
return { | ||
@@ -166,23 +168,13 @@ k: key, | ||
} else { | ||
for (const value of newValue){ | ||
node.v.push(value); | ||
} | ||
node.v.push(...newValue); | ||
return node; | ||
} | ||
node.h = 1 + Math.max(getHeight(node.l), getHeight(node.r)); | ||
const balanceFactor = getHeight(node.l) - getHeight(node.r); | ||
if (balanceFactor > 1 && key < node.l.k) { | ||
return rotateRight(node); | ||
// Rebalance the tree if the insert count reaches the threshold. | ||
// This will improve insertion performance since we won't be rebalancing the tree on every insert. | ||
// When inserting docs using `insertMultiple`, the threshold will be set to the number of docs being inserted. | ||
// We can force rebalancing the tree by setting the threshold to 1 (default). | ||
if (insertCount % rebalanceThreshold === 0) { | ||
console.log(`Rebalancing tree after ${insertCount} inserts...`); | ||
return rebalanceNode(node, key); | ||
} | ||
if (balanceFactor < -1 && key > node.r.k) { | ||
return rotateLeft(node); | ||
} | ||
if (balanceFactor > 1 && key > node.l.k) { | ||
node.l = rotateLeft(node.l); | ||
return rotateRight(node); | ||
} | ||
if (balanceFactor < -1 && key < node.r.k) { | ||
node.r = rotateRight(node.r); | ||
return rotateLeft(node); | ||
} | ||
return node; | ||
@@ -192,2 +184,21 @@ } | ||
} | ||
function rebalanceNode(node, key) { | ||
node.h = 1 + Math.max(getHeight(node.l), getHeight(node.r)); | ||
const balanceFactor = getHeight(node.l) - getHeight(node.r); | ||
if (balanceFactor > 1 && key < node.l.k) { | ||
return rotateRight(node); | ||
} | ||
if (balanceFactor < -1 && key > node.r.k) { | ||
return rotateLeft(node); | ||
} | ||
if (balanceFactor > 1 && key > node.l.k) { | ||
node.l = rotateLeft(node.l); | ||
return rotateRight(node); | ||
} | ||
if (balanceFactor < -1 && key < node.r.k) { | ||
node.r = rotateRight(node.r); | ||
return rotateLeft(node); | ||
} | ||
return node; | ||
} | ||
function getHeight(node) { | ||
@@ -194,0 +205,0 @@ return node !== null ? node.h : -1; |
@@ -0,1 +1,2 @@ | ||
import type { InsertOptions } from './methods/insert.js'; | ||
import { MODE_FULLTEXT_SEARCH, MODE_HYBRID_SEARCH, MODE_VECTOR_SEARCH } from './constants.js'; | ||
@@ -696,3 +697,3 @@ import { DocumentsStore } from './components/documents-store.js'; | ||
beforeInsert?: IIndexInsertOrRemoveHookFunction; | ||
insert: <T extends I>(implementation: IIndex<T>, index: T, prop: string, id: DocumentID, value: SearchableValue, schemaType: SearchableType, language: string | undefined, tokenizer: Tokenizer, docsCount: number) => SyncOrAsyncValue; | ||
insert: <T extends I>(implementation: IIndex<T>, index: T, prop: string, id: DocumentID, value: SearchableValue, schemaType: SearchableType, language: string | undefined, tokenizer: Tokenizer, docsCount: number, options?: InsertOptions) => SyncOrAsyncValue; | ||
afterInsert?: IIndexInsertOrRemoveHookFunction; | ||
@@ -699,0 +700,0 @@ beforeRemove?: IIndexInsertOrRemoveHookFunction; |
{ | ||
"name": "@orama/orama", | ||
"version": "2.0.22", | ||
"version": "2.0.23", | ||
"type": "module", | ||
@@ -89,4 +89,4 @@ "description": "Next generation full-text and vector search engine, written in TypeScript", | ||
"typescript": "^5.0.0", | ||
"@orama/stemmers": "2.0.22", | ||
"@orama/stopwords": "2.0.22" | ||
"@orama/stemmers": "2.0.23", | ||
"@orama/stopwords": "2.0.23" | ||
}, | ||
@@ -93,0 +93,0 @@ "engines": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
713686
6962