Advanced Features
This guide covers advanced features including connection pooling, retry mechanisms, error handling, logging, and iterator patterns.
Connection Pooling
The SDK uses connection pooling to manage gRPC connections efficiently.
Configuration
const client = new MilvusClient({
address: 'localhost:19530',
pool: {
min: 2, // Minimum pool size
max: 10, // Maximum pool size
idleTimeoutMillis: 30000, // Idle timeout
},
});Benefits
- Efficiency: Reuses connections instead of creating new ones
- Performance: Reduces connection overhead
- Resource management: Limits concurrent connections
Retry Mechanisms
Configure automatic retries for failed operations.
Configuration
const client = new MilvusClient({
address: 'localhost:19530',
maxRetries: 3, // Maximum retry attempts
retryDelay: 1000, // Delay between retries (ms)
});Retry Behavior
The SDK automatically retries on:
- Network errors
- Transient server errors
- Timeout errors
Error Handling
Error Types
import { ErrorCode } from '@zilliz/milvus2-sdk-node';
try {
await client.createCollection({ /* ... */ });
} catch (error) {
switch (error.error_code) {
case ErrorCode.CollectionNotExists:
console.error('Collection does not exist');
break;
case ErrorCode.IllegalArgument:
console.error('Invalid argument');
break;
case ErrorCode.UnexpectedError:
console.error('Unexpected error');
break;
default:
console.error('Error:', error);
}
}Common Error Codes
Success: Operation succeededCollectionNotExists: Collection not foundIllegalArgument: Invalid parameterIndexNotExist: Index not foundUnexpectedError: Unexpected server errorRateLimit: Rate limit exceededSchemaMismatch: Schema mismatch
Error Response Structure
{
error_code: 'CollectionNotExists',
reason: 'Collection my_collection does not exist',
// ... other fields
}Logging and Debugging
Log Levels
Configure logging levels:
const client = new MilvusClient({
address: 'localhost:19530',
logLevel: 'debug', // 'error', 'warn', 'info', 'debug'
logPrefix: 'milvus-client',
});Log Levels
- error: Only error messages
- warn: Warnings and errors
- info: Informational messages, warnings, and errors
- debug: All messages including debug information
Debugging
Enable trace for detailed debugging:
const client = new MilvusClient({
address: 'localhost:19530',
trace: true,
});Request Tracing (TraceID)
Track and trace individual requests using trace IDs for debugging and monitoring purposes.
Overview
The SDK automatically adds a timestamp (client-request-unixmsec) to every request. You can optionally provide a client_request_id (or client-request-id) to track specific requests across your application.
Automatic Timestamp
Every request automatically includes a client-request-unixmsec timestamp:
// This request will have client-request-unixmsec automatically added
await client.createCollection({
collection_name: 'my_collection',
fields: [...],
// Timestamp is added automatically, no configuration needed
});Using TraceID
Add a trace ID to track specific requests:
// Recommended: use client_request_id (JavaScript/TypeScript convention)
const traceId = `trace-${Date.now()}`;
await client.createCollection({
collection_name: 'my_collection',
fields: [...],
client_request_id: traceId,
});
// Alternative: use client-request-id (compatible with pymilvus)
await client.createCollection({
collection_name: 'my_collection',
fields: [...],
'client-request-id': traceId,
});Note: If both formats are provided, client_request_id takes priority (JavaScript/TypeScript convention).
Supported Operations
All API methods that extend GrpcTimeOut support trace IDs:
// Insert with trace ID
await client.insert({
collection_name: 'my_collection',
data: [
{ id: 1, vector: [0.1, 0.2, 0.3] },
],
client_request_id: 'insert-trace-123',
});
// Search with trace ID
await client.search({
collection_name: 'my_collection',
vector: [0.1, 0.2, 0.3],
limit: 10,
client_request_id: 'search-trace-456',
});
// Query with trace ID
await client.query({
collection_name: 'my_collection',
expr: 'id > 100',
client_request_id: 'query-trace-789',
});
// All other operations support trace IDs
await client.createIndex({
collection_name: 'my_collection',
field_name: 'vector',
index_type: 'IVF_FLAT',
client_request_id: 'index-trace-101',
});Use Cases
- Request Tracking: Track requests across distributed systems
- Debugging: Identify specific requests in logs
- Performance Monitoring: Correlate trace IDs with performance metrics
- Error Investigation: Trace errors back to specific requests
Implementation Details
- Trace IDs are passed through gRPC metadata
- Both
client_request_idandclient-request-idformats are supported - Trace IDs are automatically extracted from request parameters
- The timestamp
client-request-unixmsecis automatically added by the interceptor - No need to modify API method implementations
Iterator Patterns
Query Iterator
Iterate through large query results:
const iterator = await client.queryIterator({
collection_name: 'my_collection',
expr: 'age > 25',
output_fields: ['id', 'text'],
batch_size: 100,
});
while (true) {
const batch = await iterator.next();
if (batch.done) break;
console.log('Batch:', batch.value);
}Search Iterator
Iterate through large search results:
const iterator = await client.searchIterator({
collection_name: 'my_collection',
data: [[0.1, 0.2, 0.3, 0.4]],
limit: 10000,
batch_size: 100,
});
while (true) {
const batch = await iterator.next();
if (batch.done) break;
console.log('Batch:', batch.value);
}Sparse Vectors
Work with sparse vector data:
// Array format
const sparseVector = [1.0, undefined, undefined, 2.5, undefined];
// Dictionary format
const sparseVector = { '0': 1.0, '3': 2.5 };
// CSR format
const sparseVector = {
indices: [0, 3],
values: [1.0, 2.5],
};
// COO format
const sparseVector = [
{ index: 0, value: 1.0 },
{ index: 3, value: 2.5 },
];
await client.insert({
collection_name: 'my_collection',
data: [
{
sparse_vector: sparseVector,
},
],
});Binary Vectors
Work with binary vector data:
// Binary vector: length must be dim / 8
const binaryVector = [1, 0, 1, 0, 1, 0, 1, 0]; // For dim=64
await client.insert({
collection_name: 'my_collection',
data: [
{
binary_vector: binaryVector,
},
],
});Float16/BFloat16 Vectors
Use transformers for Float16 and BFloat16 vectors:
import { f32ArrayToF16Bytes } from '@zilliz/milvus2-sdk-node';
await client.insert({
collection_name: 'my_collection',
data: [
{
vector: [0.1, 0.2, 0.3, 0.4], // f32 array
},
],
transformers: {
vector: (data) => f32ArrayToF16Bytes(data),
},
});Dynamic Fields
Enable dynamic fields for flexible schemas:
// Create collection with dynamic fields
await client.createCollection({
collection_name: 'my_collection',
fields: [
{
name: 'id',
data_type: DataType.Int64,
is_primary_key: true,
autoID: true,
},
{
name: 'vector',
data_type: DataType.FloatVector,
dim: 128,
},
],
enable_dynamic_field: true,
});
// Insert data with dynamic fields
await client.insert({
collection_name: 'my_collection',
data: [
{
vector: [/* ... */],
dynamic_field_1: 'value1', // Automatically added
dynamic_field_2: 123, // Automatically added
},
],
});Performance Monitoring
Get Metrics
Get system metrics:
const metrics = await client.getMetric({
request: {
metric_type: 'system_info',
},
});
console.log('Metrics:', metrics);Replica Management
Get Replicas
Get replica information:
const replicas = await client.getReplicas({
collection_name: 'my_collection',
});
console.log('Replicas:', replicas.replicas);Best Practices
- Connection pooling: Configure appropriate pool sizes
- Retry configuration: Set reasonable retry limits
- Error handling: Always handle errors appropriately
- Logging: Use appropriate log levels for your environment
- Iterators: Use iterators for large result sets
- Monitoring: Monitor metrics for performance optimization
Next Steps
- Learn about Best Practices
- Explore HTTP Client
- Check out Examples & Tutorials