Adds new vectors to the encrypted index or updates existing vectors if they have the same ID. This operation supports two distinct calling patterns for maximum flexibility.
Method Overloads
Pattern 1: VectorItem Array
async upsert ({
items? : VectorItem [], // Pattern 1: Provide items array
ids? : string [], // Pattern 2: Provide ids and vectors together
vectors? : number [][], // Pattern 2: Provide ids and vectors together
metadata? : ( Record < string , unknown > | null )[], // Pattern 2: Optional metadata per vector
contents? : ( string | null )[] // Pattern 2: Optional contents per vector
}): Promise < UpsertResponse >
// Note: Must provide either 'items' OR both 'ids' and 'vectors'
Parameters
Pattern 1: VectorItem Array
Parameter Type Description itemsVectorItem[]Array of vector items to insert or update in the index
Pattern 2: Parallel Arrays
Parameter Type Description idsstring[]Array of ID strings for each vector vectorsnumber[][] | Float32ArrayArray of vector embeddings corresponding to each ID metadata(Record<string, unknown> | null)[](Optional) Array of metadata objects corresponding to each IDcontents(string | null)[](Optional) Array of content strings corresponding to each ID
Passing a Float32Array automatically uses an optimized binary transfer format for better performance with large batches.
VectorItem Structure
Each VectorItem must contain an id and vector, with optional fields:
Field Type Required Description idstringYes Unique identifier for the vector item vectornumber[]Yes* The vector representation. *Required unless contents is provided (for auto-embedding via embedding model) contentsstring | BufferOptional Content associated with the vector (accepts both strings and bytes, encoded to bytes and encrypted before storage) metadataobjectOptional Additional structured data associated with the vector
The contents field accepts both strings and Buffers. All contents are encoded to bytes and encrypted before storage, and will be returned as decoded UTF-8 strings when retrieved with get().
Returns
Promise<UpsertResponse>: A Promise that resolves to a response object containing the operation status, message, and count of upserted vectors. See the UpsertResponse type for more details.
Exceptions
Throws if the API request fails due to network connectivity issues.
Throws if authentication fails (invalid API key).
Throws if the encryption key is invalid for the specified index.
Throws if there are internal server errors preventing the upsert.
Throws detailed validation errors for invalid VectorItem objects.
Throws if vector dimensions don’t match the index configuration.
Throws if required fields are missing from vector items.
Throws if array lengths don’t match in parallel array format.
Throws if vector elements are not finite numbers.
Example Usage
Pattern 1: VectorItem Array (Recommended)
import { Client , VectorItem , UpsertResponse } from 'cyborgdb' ;
const client = new Client ({ baseUrl: 'http://localhost:8000' , apiKey: 'your-api-key' });
// Load an existing index
const indexKey = new Uint8Array ( Buffer . from ( 'your-stored-hex-key' , 'hex' ));
const index = await client . loadIndex ({ indexName: 'my-vector-index' , indexKey });
// Prepare vector items with rich metadata
const vectorItems : VectorItem [] = [
{
id: 'doc1' ,
vector: [ 0.1 , 0.2 , 0.3 , /* ... additional dimensions */ ],
contents: 'This is the content of the first document' ,
metadata: {
title: 'Introduction to Machine Learning' ,
author: 'Dr. Smith' ,
category: 'education' ,
tags: [ 'ml' , 'ai' , 'tutorial' ],
published_date: '2024-01-15' ,
word_count: 1250
}
},
{
id: 'doc2' ,
vector: [ 0.4 , 0.5 , 0.6 , /* ... additional dimensions */ ],
contents: 'This is the content of the second document' ,
metadata: {
title: 'Advanced Neural Networks' ,
author: 'Dr. Jones' ,
category: 'research' ,
tags: [ 'neural-networks' , 'deep-learning' ],
published_date: '2024-01-20' ,
word_count: 2100
}
}
];
// Upsert vectors
try {
const result : UpsertResponse = await index . upsert ({ items: vectorItems });
console . log ( 'Upsert result:' , result );
console . log ( `Status: ${ result . status } ` );
console . log ( `Upserted count: ${ result . upsertedCount } ` );
console . log ( `Successfully added ${ vectorItems . length } vectors to the index` );
} catch ( error : any ) {
console . error ( 'Upsert failed:' , error . message );
}
Pattern 2: Parallel Arrays (For Bulk Operations)
// Efficient for bulk operations with parallel arrays
const ids = [ 'vec1' , 'vec2' , 'vec3' ];
const vectors = [
[ 0.1 , 0.2 , 0.3 , 0.4 ],
[ 0.5 , 0.6 , 0.7 , 0.8 ],
[ 0.9 , 1.0 , 1.1 , 1.2 ]
];
try {
const result = await index . upsert ({ ids , vectors });
console . log ( 'Bulk upsert result:' , result );
} catch ( error : any ) {
console . error ( 'Bulk upsert failed:' , error . message );
}
// With optional metadata and contents
const metadata = [
{ title: 'Document 1' , category: 'research' },
{ title: 'Document 2' , category: 'tutorial' },
null // no metadata for third vector
];
const contents = [
'First document content' ,
'Second document content' ,
null // no content for third vector
];
try {
const result = await index . upsert ({ ids , vectors , metadata , contents });
console . log ( 'Bulk upsert with metadata:' , result );
} catch ( error : any ) {
console . error ( 'Bulk upsert failed:' , error . message );
}
Updating Existing Vectors
// Add initial vector
const initialVector : VectorItem = {
id: 'updatable_doc' ,
vector: [ 0.1 , 0.2 , 0.3 , 0.4 ],
contents: 'Original content' ,
metadata: { version: 1 , status: 'draft' }
};
await index . upsert ({ items: [ initialVector ] });
// Update the same vector with new data
const updatedVector : VectorItem = {
id: 'updatable_doc' , // Same ID - will update existing
vector: [ 0.15 , 0.25 , 0.35 , 0.45 ], // Updated vector
contents: 'Updated content with more information' ,
metadata: {
version: 2 ,
status: 'published' ,
updated_date: '2024-01-25' ,
editor: 'John Doe'
}
};
try {
const updateResult = await index . upsert ({ items: [ updatedVector ] });
console . log ( 'Update result:' , updateResult );
// Verify the update
const retrievedVector = await index . get ({ ids: [ 'updatable_doc' ] });
console . log ( 'Updated vector metadata:' , retrievedVector [ 0 ]. metadata );
} catch ( error : any ) {
console . error ( 'Update failed:' , error . message );
}
Batch Processing with Error Handling
async function processBatchDocuments (
index : EncryptedIndex ,
documents : Array <{
id : string ;
title : string ;
content : string ;
author : string ;
category : string ;
vector : number [];
}>
) : Promise <{ success : boolean ; count : number ; message : string }> {
// Convert documents to VectorItem format
const vectorItems : VectorItem [] = documents . map ( doc => ({
id: doc . id ,
vector: doc . vector ,
contents: doc . content ,
metadata: {
title: doc . title ,
author: doc . author ,
category: doc . category ,
word_count: doc . content . split ( ' ' ). length ,
char_count: doc . content . length ,
processed_date: new Date (). toISOString ()
}
}));
try {
console . log ( `Processing batch of ${ vectorItems . length } documents` );
const result = await index . upsert ({ items: vectorItems });
console . log ( 'Batch upsert completed:' , result );
return {
success: true ,
count: vectorItems . length ,
message: `Successfully processed ${ vectorItems . length } documents`
};
} catch ( error : any ) {
console . error ( 'Batch upsert failed:' , error . message );
// Provide detailed error information
if ( error . message . includes ( 'Invalid VectorItem' )) {
console . error ( 'Validation failed - check your vector data format' );
} else if ( error . message . includes ( 'dimension' )) {
console . error ( 'Vector dimension mismatch - check index configuration' );
}
return {
success: false ,
count: 0 ,
message: `Batch processing failed: ${ error . message } `
};
}
}
// Usage
const documents = [
{
id: 'article_001' ,
title: 'Getting Started with TypeScript' ,
content: 'TypeScript is a powerful superset of JavaScript...' ,
author: 'Jane Developer' ,
category: 'programming' ,
vector: [ 0.1 , 0.2 , 0.3 , 0.4 ]
},
{
id: 'article_002' ,
title: 'React Best Practices' ,
content: 'When building React applications, it is important...' ,
author: 'John React' ,
category: 'frontend' ,
vector: [ 0.5 , 0.6 , 0.7 , 0.8 ]
}
];
const batchResult = await processBatchDocuments ( index , documents );
console . log ( 'Batch processing result:' , batchResult );
// Standard successful upsert response
{
"status" : "success" ,
"message" : "Upserted 5 vectors"
}