The VectorDB operator stores documents and embeddings in vector databases for similarity search. This document covers OpenSearch-specific configuration.
When configured with provider: "opensearch", the operator supports multiple KNN engines, algorithms, incremental updates, and query capabilities.
| Engine | Algorithms | Best For | Notes |
|---|---|---|---|
| FAISS | HNSW, IVF | Large-scale similarity search | Recommended for production |
| Lucene | HNSW | Native OpenSearch integration | Good balance of speed and accuracy |
| nmslib | HNSW | Legacy support | Deprecated in OpenSearch 2.13+ |
| jVector | HNSW | Java-based implementation | Requires k-NN plugin |
| Algorithm | Speed | Accuracy | Memory | Use Case |
|---|---|---|---|---|
| HNSW | Fast | High | Medium | General purpose, recommended |
| IVF | Very Fast | Medium | Low | Large datasets, speed priority |
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
provider |
string | No | “opensearch” | Vector database type |
index_name |
string | Yes | - | Name of the OpenSearch index |
doc_id_column |
string | No | “doc_id_hash” | Column containing document IDs |
embeddings_column |
string | No | “embeddings” | Column containing embeddings |
vector_dimension |
integer | No | 384 | Dimension of vector embeddings |
create_index |
boolean | No | true | Create index if it doesn’t exist |
batch_size |
integer | No | 100 | Documents per batch |
provider_config |
object | Yes | - | Provider-specific configuration (see below) |
Connection and engine-specific parameters are configured inside the provider_config nested dictionary for architectural separation between generic and provider-specific settings.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
host |
string | Yes | - | OpenSearch server host |
port |
integer | No | 9200 | OpenSearch server port |
username |
string | No | - | Username for basic authentication |
password |
string | No | - | Password for basic authentication |
use_ssl |
boolean | No | false | Use SSL connection |
verify_certs |
boolean | No | false | Verify SSL certificates |
aws_auth |
boolean | No | false | Use AWS IAM authentication |
aws_region |
string | No | - | AWS region for authentication |
jwt_token |
string | No | - | JWT token for Bearer authentication |
engine |
string | No | “faiss” | KNN engine (faiss, lucene, nmslib, jvector) |
algorithm |
string | No | “hnsw” | KNN algorithm (hnsw, ivf) |
space_type |
string | No | “l2” | Similarity metric (l2, cosine, inner_product) |
engine_parameters |
object | No | {} | Custom engine-specific parameters |
Note: Only one authentication method can be used at a time: basic auth (username/password), AWS IAM (aws_auth), or JWT token (jwt_token).
{
"ef_construction": 128,
"m": 24
}
{
"nlist": 128,
"nprobe": 8
}
{
"ef_construction": 128,
"m": 16
}
from docpipe.core.operators.vectordb import VectorDBOperator
from docpipe.common.constants.operator_constants import OperatorConstants
import pyarrow as pa
import numpy as np
config = {
"provider": "opensearch",
"index_name": "my_documents",
"vector_dimension": 384,
OperatorConstants.Config.PROVIDER_CONFIG: {
"host": "localhost",
"port": 9200,
"username": "admin",
"password": "<your-opensearch-password>",
"use_ssl": False,
OperatorConstants.VectorDB.ENGINE: "faiss",
OperatorConstants.VectorDB.ALGORITHM: "hnsw",
OperatorConstants.VectorDB.SPACE_TYPE: "l2"
},
"available_features": {
"doc_id_hash": {
"available_for_vector_db": True,
"mandatory_for_vector_db": True,
"type": "string",
"is_primary": True
},
"content": {
"available_for_vector_db": True,
"type": "string"
},
"embeddings": {
"available_for_vector_db": True,
"mandatory_for_vector_db": True,
"type": "vector"
}
},
"feature_mappings": {
"doc_id_hash": "id",
"content": "text",
"embeddings": "vector"
}
}
# Create sample data
data = {
"doc_id_hash": ["doc1", "doc2"],
"content": ["First document", "Second document"],
"embeddings": [np.random.rand(384).tolist(), np.random.rand(384).tolist()]
}
table = pa.table(data)
# Index documents
operator = VectorDBOperator(config)
result_tables, metadata = operator.transform(table)
print(f"Indexed {metadata['processed_docs']} documents")
from docpipe.common.constants.operator_constants import OperatorConstants
config = {
"provider": "opensearch",
"index_name": "semantic_search",
"vector_dimension": 768,
OperatorConstants.Config.PROVIDER_CONFIG: {
"host": "localhost",
"port": 9200,
OperatorConstants.VectorDB.ENGINE: "lucene",
OperatorConstants.VectorDB.ALGORITHM: "hnsw",
OperatorConstants.VectorDB.SPACE_TYPE: "cosine",
OperatorConstants.VectorDB.ENGINE_PARAMETERS: {
"ef_construction": 256,
"m": 32
}
}
}
from docpipe.common.constants.operator_constants import OperatorConstants
config = {
"provider": "opensearch",
"index_name": "production_docs",
OperatorConstants.Config.PROVIDER_CONFIG: {
"host": "search-mydomain.us-east-1.es.amazonaws.com",
"port": 443,
"use_ssl": True,
OperatorConstants.VectorDB.ENGINE: "faiss",
OperatorConstants.VectorDB.ALGORITHM: "hnsw",
OperatorConstants.VectorDB.AWS_AUTH: True,
OperatorConstants.VectorDB.AWS_REGION: "us-east-1"
}
}
### Example 4: JWT Token Authentication
For AWS OpenSearch or custom deployments with JWT authentication:
```python
from docpipe.common.constants.operator_constants import OperatorConstants
import os
config = {
"provider": "opensearch",
"index_name": "jwt_secured_docs",
"vector_dimension": 384,
OperatorConstants.Config.PROVIDER_CONFIG: {
"host": "search-mydomain.us-east-1.es.amazonaws.com",
"port": 443,
"use_ssl": True,
"verify_certs": True,
OperatorConstants.VectorDB.ENGINE: "faiss",
OperatorConstants.VectorDB.ALGORITHM: "hnsw",
OperatorConstants.VectorDB.JWT_TOKEN: os.getenv("OPENSEARCH_JWT_TOKEN")
}
}
Important: Only one authentication method can be used at a time (basic auth, AWS IAM, or JWT token).
Environment Variable Setup:
# pragma: allowlist secret
export OPENSEARCH_JWT_TOKEN="your-jwt-token-here"
Security Best Practices:
### Example 4: Query Documents
```python
# Query documents by name
docs = operator.query_by_doc_names(["doc1", "doc2"], fields=["content", "embeddings"])
print(f"Found {len(docs)} documents")
# Get document count
count = operator.get_document_count()
print(f"Total documents: {count}")
# Delete documents
success, failed = operator.delete_documents_by_ids(["doc1", "doc2"])
print(f"Deleted {success} documents, {failed} failed")
{
"flow_name": "complete-document-pipeline",
"description": "Complete document processing pipeline: Ingest -> Extract -> Chunk -> Embed -> Store in OpenSearch",
"global_config": {
"doc_column": "content",
"disable_validation": true,
"force_ingest": true,
"storage": "in-memory",
"execute_type": "local"
},
"flow": [
{
"type": "ingest_source",
"name": "ingest_source_filesystem",
"config": {
"provider": "filesystem",
"connection_params": {"paths": ["./sample_documents"]},
"include_filter": "pdf,txt,docx"
}
},
{
"type": "extract_operator",
"name": "extract_with_docling",
"config": {
"text_extraction": {
"provider": "docling_library",
"doc_column": "content"
},
"entity_extraction": {
"provider": "none"
}
},
"depends_on": [
"ingest_source_filesystem"
]
},
{
"type": "chunker",
"name": "simple_chunker",
"config": {
"chunk_type": "simple",
"chunk_size": 512,
"chunk_overlap": 50,
"retain_original_content": false
},
"depends_on": [
"extract_with_docling"
]
},
{
"type": "embeddings",
"name": "ollama_embeddings",
"config": {
"provider": "litellm",
"provider_config": {
"model_id": "openai/nomic-embed-text",
"api_base": "http://localhost:11434/v1",
"api_key": "<ollama-api-key>"
},
"embeddings_column": "embeddings",
"overlap_ratio": 0.1
},
"depends_on": [
"simple_chunker"
]
},
{
"type": "vectordb",
"name": "opensearch_vector_store",
"config": {
"provider": "opensearch",
"index_name": "sample-documents-index",
"doc_id_column": "doc_id_hash",
"embeddings_column": "embeddings",
"vector_dimension": 768,
"create_index": true,
"provider_config": {
"host": "localhost",
"port": 9200,
"username": "${OPENSEARCH_USERNAME}",
"password": "${OPENSEARCH_PASSWORD}",
"use_ssl": false,
"verify_certs": false,
"batch_size": 100,
"engine": "faiss",
"algorithm": "hnsw",
"space_type": "l2"
},
"available_features": {
"doc_id_hash": {
"name": "Document ID",
"available_for_vector_db": true,
"mandatory_for_vector_db": true,
"type": "string",
"is_primary": true
},
"content": {
"name": "Content",
"available_for_vector_db": true,
"type": "string"
},
"doc_name": {
"name": "Document Name",
"available_for_vector_db": true,
"type": "string"
},
"file_path": {
"name": "File Path",
"available_for_vector_db": true,
"type": "string"
},
"embeddings": {
"name": "Embeddings",
"available_for_vector_db": true,
"mandatory_for_vector_db": true,
"type": "vector"
},
"chunk_id": {
"name": "Chunk ID",
"available_for_vector_db": true,
"type": "string"
},
"chunk_index": {
"name": "Chunk Index",
"available_for_vector_db": true,
"type": "integer"
}
},
"feature_mappings": {
"doc_id_hash": "pk",
"content": "text",
"name": "doc_name",
"path": "file_path",
"embeddings": "vector_embeddings",
"chunk_id": "chunk_id",
"chunk_index": "chunk_index"
}
},
"depends_on": [
"ollama_embeddings"
]
}
]
}
The operator uses size-aware batching with a default limit of 3MB per batch:
config = {
"batch_size": 500, # Maximum documents per batch
# Actual batch size may be smaller if 3MB limit is reached
}
from docpipe.common.constants.operator_constants import OperatorConstants
OperatorConstants.Config.PROVIDER_CONFIG: {
OperatorConstants.VectorDB.ENGINE: "faiss",
OperatorConstants.VectorDB.ALGORITHM: "hnsw",
OperatorConstants.VectorDB.ENGINE_PARAMETERS: {
"ef_construction": 128, # Higher = better accuracy, slower indexing
"m": 24 # Higher = better accuracy, more memory
}
}
OperatorConstants.Config.PROVIDER_CONFIG: {
OperatorConstants.VectorDB.ENGINE: "faiss",
OperatorConstants.VectorDB.ALGORITHM: "ivf",
OperatorConstants.VectorDB.ENGINE_PARAMETERS: {
"nlist": 128, # Number of clusters
"nprobe": 8 # Clusters to search (higher = more accurate, slower)
}
}
OperatorConstants.Config.PROVIDER_CONFIG: {
OperatorConstants.VectorDB.ENGINE: "lucene",
OperatorConstants.VectorDB.ALGORITHM: "hnsw",
OperatorConstants.VectorDB.ENGINE_PARAMETERS: {
"ef_construction": 128,
"m": 16 # Lucene typically uses lower m values
}
}
The operator provides detailed error tracking:
result_tables, metadata = operator.transform(table)
print(f"Total documents: {metadata['total_docs']}")
print(f"Processed: {metadata['processed_docs']}")
print(f"Failed: {metadata['failed_docs_count']}")
print(f"Skipped: {metadata['skipped_docs_count']}")
print(f"Batches: {metadata['number_of_batches']}")
# Check failed documents
for failed_doc in metadata['failed_docs']:
print(f"Failed: {failed_doc['name']} - {failed_doc['reason']}")
create_index: true for first runSee docs/integrations/opensearch/ for troubleshooting and setup guides.