Advanced Operations
This guide covers advanced features available in ekoDB client libraries, including search operations, chat functionality, and real-time data handling.
For complete, runnable examples, visit the ekoDB Examples Repository. It contains 105 working examples across all languages.
Search Operations
ekoDB provides powerful search capabilities including full-text search, fuzzy search, and vector search.
Full-Text Search
Search across all fields in your documents:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
use ekodb_client::{Client, SearchQuery};
let search = SearchQuery::builder()
.query("database")
.min_score(0.1)
.limit(10)
.build();
let results = client.search("articles", search).await?;
for result in results.results {
println!("Score: {:.4} - {:?}", result.score, result.record);
}
from ekodb_client import Client, SearchQuery
search = SearchQuery(
query="database",
min_score=0.1,
limit=10
)
results = client.search("articles", search)
for result in results.results:
print(f"Score: {result.score:.4f} - {result.record}")
import { EkoDBClient, SearchQuery } from "@ekodb/ekodb-client";
const search: SearchQuery = {
query: "database",
minScore: 0.1,
limit: 10
};
const results = await client.search("articles", search);
for (const result of results.results) {
console.log(`Score: ${result.score.toFixed(4)} - ${JSON.stringify(result.record)}`);
}
const results = await client.search("articles", {
query: "database",
minScore: 0.1,
limit: 10
});
for (const result of results.results) {
console.log(`Score: ${result.score.toFixed(4)} - ${JSON.stringify(result.record)}`);
}
import io.ekodb.client.EkoDBClient
val results = client.search("articles") {
query = "database"
minScore = 0.1
limit = 10
}
results.results.forEach { result ->
println("Score: ${"%.4f".format(result.score)} - ${result.record}")
}
import ekodb "github.com/ekoDB/ekodb-client-go"
searchQuery := ekodb.SearchQuery{
Query: "database",
MinScore: 0.1,
Limit: 10,
}
results, err := client.Search("articles", searchQuery)
if err != nil {
log.Fatal(err)
}
for _, result := range results.Results {
fmt.Printf("Score: %.4f - %+v\n", result.Score, result.Record)
}
Field-Weighted Search
Search with custom field weights to prioritize certain fields:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
use std::collections::HashMap;
let mut weights = HashMap::new();
weights.insert("title".to_string(), 2.0);
weights.insert("description".to_string(), 1.0);
let search = SearchQuery::builder()
.query("rust database")
.fields(vec!["title".to_string(), "description".to_string()])
.weights(weights)
.limit(5)
.build();
let results = client.search("articles", search).await?;
search = SearchQuery(
query="rust database",
fields=["title", "description"],
weights={"title": 2.0, "description": 1.0},
limit=5
)
results = client.search("articles", search)
const search: SearchQuery = {
query: "rust database",
fields: ["title", "description"],
weights: { title: 2.0, description: 1.0 },
limit: 5
};
const results = await client.search("articles", search);
const results = await client.search("articles", {
query: "rust database",
fields: ["title", "description"],
weights: { title: 2.0, description: 1.0 },
limit: 5
});
val results = client.search("articles") {
query = "rust database"
fields = listOf("title", "description")
weights = mapOf("title" to 2.0, "description" to 1.0)
limit = 5
}
searchQuery := ekodb.SearchQuery{
Query: "rust database",
Fields: []string{"title", "description"},
Weights: map[string]float64{"title": 2.0, "description": 1.0},
Limit: 5,
}
results, err := client.Search("articles", searchQuery)
Fuzzy Search
Enable typo tolerance with fuzzy matching:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let search = SearchQuery::builder()
.query("databse") // Typo: "databse" instead of "database"
.fuzzy(true)
.fuzziness(2) // Allow up to 2 character differences
.limit(10)
.build();
let results = client.search("articles", search).await?;
search = SearchQuery(
query="databse", # Typo
fuzzy=True,
fuzziness=2,
limit=10
)
results = client.search("articles", search)
const search: SearchQuery = {
query: "databse", // Typo
fuzzy: true,
fuzziness: 2,
limit: 10
};
const results = await client.search("articles", search);
const results = await client.search("articles", {
query: "databse", // Typo
fuzzy: true,
fuzziness: 2,
limit: 10
});
val results = client.search("articles") {
query = "databse" // Typo
fuzzy = true
fuzziness = 2
limit = 10
}
searchQuery := ekodb.SearchQuery{
Query: "databse", // Typo
Fuzzy: true,
Fuzziness: 2,
Limit: 10,
}
results, err := client.Search("articles", searchQuery)
Vector Search
Perform semantic similarity search using embeddings:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
// First, create a collection with vector index
let schema = Schema::builder()
.add_field("content", FieldType::String)
.add_field("embedding", FieldType::Vector(384)) // 384-dimensional vector
.build();
client.create_collection("documents", schema).await?;
// Insert document with embedding
let mut doc = Record::new();
doc.insert("content", "ekoDB is a high-performance database");
doc.insert("embedding", vec![0.1, 0.2, 0.3, /* ... 384 dimensions */]);
client.insert("documents", doc).await?;
// Search by vector similarity
let query_vector = vec![0.1, 0.2, 0.3, /* ... */];
let search = SearchQuery::builder()
.vector(query_vector)
.limit(10)
.build();
let results = client.search("documents", search).await?;
# Create collection with vector index
schema = Schema(
fields={
"content": FieldType.String(),
"embedding": FieldType.Vector(384)
}
)
client.create_collection("documents", schema)
# Insert with embedding
doc = {
"content": "ekoDB is a high-performance database",
"embedding": [0.1, 0.2, 0.3, ...] # 384 dimensions
}
client.insert("documents", doc)
# Vector search
query_vector = [0.1, 0.2, 0.3, ...]
search = SearchQuery(vector=query_vector, limit=10)
results = client.search("documents", search)
// Create collection with vector index
const schema = {
fields: {
content: { type: "String" },
embedding: { type: "Vector", dimensions: 384 }
}
};
await client.createCollection("documents", schema);
// Insert with embedding
await client.insert("documents", {
content: "ekoDB is a high-performance database",
embedding: [0.1, 0.2, 0.3, /* ... 384 dimensions */]
});
// Vector search
const queryVector = [0.1, 0.2, 0.3, /* ... */];
const results = await client.search("documents", {
vector: queryVector,
limit: 10
});
// Insert with embedding
await client.insert("documents", {
content: "ekoDB is a high-performance database",
embedding: [0.1, 0.2, 0.3, /* ... 384 dimensions */]
});
// Vector search
const queryVector = [0.1, 0.2, 0.3, /* ... */];
const results = await client.search("documents", {
vector: queryVector,
limit: 10
});
// Insert with embedding
val doc = Record.new()
.insert("content", "ekoDB is a high-performance database")
.insert("embedding", listOf(0.1, 0.2, 0.3, /* ... 384 dimensions */))
client.insert("documents", doc)
// Vector search
val queryVector = listOf(0.1, 0.2, 0.3, /* ... */)
val results = client.search("documents") {
vector = queryVector
limit = 10
}
// Create collection with vector index
schema := ekodb.NewSchemaBuilder().
AddField("content", ekodb.NewFieldTypeSchemaBuilder("String").Build()).
AddField("embedding", ekodb.NewFieldTypeSchemaBuilder("Vector").
Dimensions(384).
Build()).
Build()
client.CreateCollection("documents", schema)
// Insert with embedding
doc := ekodb.Record{
"content": "ekoDB is a high-performance database",
"embedding": []float64{0.1, 0.2, 0.3, /* ... 384 dimensions */},
}
client.Insert("documents", doc)
// Vector search
queryVector := []float64{0.1, 0.2, 0.3, /* ... */}
searchQuery := ekodb.SearchQuery{
Vector: queryVector,
Limit: 10,
}
results, err := client.Search("documents", searchQuery)
Hybrid Search
Combine text and vector search for best results:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let search = SearchQuery::builder()
.query("database performance") // Text query
.vector(query_vector) // Vector query
.limit(10)
.build();
let results = client.search("documents", search).await?;
search = SearchQuery(
query="database performance", # Text query
vector=query_vector, # Vector query
limit=10
)
results = client.search("documents", search)
const search: SearchQuery = {
query: "database performance", // Text query
vector: queryVector, // Vector query
limit: 10
};
const results = await client.search("documents", search);
const results = await client.search("documents", {
query: "database performance", // Text query
vector: queryVector, // Vector query
limit: 10
});
val results = client.search("documents") {
query = "database performance" // Text query
vector = queryVector // Vector query
limit = 10
}
searchQuery := ekodb.SearchQuery{
Query: "database performance", // Text query
Vector: queryVector, // Vector query
Limit: 10,
}
results, err := client.Search("documents", searchQuery)
Chat Operations
Build AI-powered chat applications with built-in context management and session handling.
Basic Chat
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
use ekodb_client::chat::{ChatClient, ChatMessage};
// Create chat client
let chat = ChatClient::new(client, "products");
// Send a message
let response = chat.send_message(
"What products do you have?",
"gpt-4"
).await?;
println!("AI: {}", response.content);
from ekodb_client import ChatClient
# Create chat client
chat = ChatClient(client, "products")
# Send a message
response = chat.send_message(
"What products do you have?",
model="gpt-4"
)
print(f"AI: {response.content}")
import { ChatClient } from "@ekodb/ekodb-client";
// Create chat client
const chat = new ChatClient(client, "products");
// Send a message
const response = await chat.sendMessage(
"What products do you have?",
"gpt-4"
);
console.log(`AI: ${response.content}`);
const { ChatClient } = require("@ekodb/ekodb-client");
// Create chat client
const chat = new ChatClient(client, "products");
// Send a message
const response = await chat.sendMessage(
"What products do you have?",
"gpt-4"
);
console.log(`AI: ${response.content}`);
import io.ekodb.client.ChatClient
// Create chat client
val chat = ChatClient(client, "products")
// Send a message
val response = chat.sendMessage(
"What products do you have?",
model = "gpt-4"
)
println("AI: ${response.content}")
import "github.com/ekoDB/ekodb-client-go"
// Create chat client
chat := ekodb.NewChatClient(client, "products")
// Send a message
response, err := chat.SendMessage(
"What products do you have?",
"gpt-4",
)
fmt.Printf("AI: %s\n", response.Content)
Chat Sessions
Manage conversation history with sessions:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
// Create a new session
let session = chat.create_session("Customer Support Chat").await?;
// Send messages in the session
let response1 = chat.send_message_in_session(
&session.id,
"What's the price of ekoDB Pro?",
"gpt-4"
).await?;
let response2 = chat.send_message_in_session(
&session.id,
"What features does it include?",
"gpt-4"
).await?;
// Get session history
let messages = chat.get_session_messages(&session.id).await?;
println!("Total messages: {}", messages.len());
# Create a new session
session = chat.create_session("Customer Support Chat")
# Send messages in the session
response1 = chat.send_message_in_session(
session.id,
"What's the price of ekoDB Pro?",
model="gpt-4"
)
response2 = chat.send_message_in_session(
session.id,
"What features does it include?",
model="gpt-4"
)
# Get session history
messages = chat.get_session_messages(session.id)
print(f"Total messages: {len(messages)}")
// Create a new session
const session = await chat.createSession("Customer Support Chat");
// Send messages in the session
const response1 = await chat.sendMessageInSession(
session.id,
"What's the price of ekoDB Pro?",
"gpt-4"
);
const response2 = await chat.sendMessageInSession(
session.id,
"What features does it include?",
"gpt-4"
);
// Get session history
const messages = await chat.getSessionMessages(session.id);
console.log(`Total messages: ${messages.length}`);
// Create a new session
const session = await chat.createSession("Customer Support Chat");
// Send messages in the session
const response1 = await chat.sendMessageInSession(
session.id,
"What's the price of ekoDB Pro?",
"gpt-4"
);
const response2 = await chat.sendMessageInSession(
session.id,
"What features does it include?",
"gpt-4"
);
// Get session history
const messages = await chat.getSessionMessages(session.id);
console.log(`Total messages: ${messages.length}`);
// Create a new session
val session = chat.createSession("Customer Support Chat")
// Send messages in the session
val response1 = chat.sendMessageInSession(
session.id,
"What's the price of ekoDB Pro?",
model = "gpt-4"
)
val response2 = chat.sendMessageInSession(
session.id,
"What features does it include?",
model = "gpt-4"
)
// Get session history
val messages = chat.getSessionMessages(session.id)
println("Total messages: ${messages.size}")
// Create a new session
session, err := chat.CreateSession("Customer Support Chat")
// Send messages in the session
response1, err := chat.SendMessageInSession(
session.ID,
"What's the price of ekoDB Pro?",
"gpt-4",
)
response2, err := chat.SendMessageInSession(
session.ID,
"What features does it include?",
"gpt-4",
)
// Get session history
messages, err := chat.GetSessionMessages(session.ID)
fmt.Printf("Total messages: %d\n", len(messages))
Real-Time Operations
WebSocket Queries
Subscribe to real-time data changes:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
use ekodb_client::WebSocketClient;
// Connect to WebSocket
let ws_url = "wss://your-subdomain.production.google.ekodb.net/ws";
let mut ws_client = client.websocket(ws_url).await?;
// Subscribe to collection changes
let results = ws_client.find_all("users").await?;
// Process real-time updates
for record in results {
println!("New/Updated record: {:?}", record);
}
ws_client.close().await?;
# Connect to WebSocket
ws_url = "wss://your-subdomain.production.google.ekodb.net/ws"
ws_client = client.websocket(ws_url)
# Subscribe to collection changes
results = ws_client.find_all("users")
# Process real-time updates
for record in results:
print(f"New/Updated record: {record}")
ws_client.close()
// Connect to WebSocket
const wsUrl = "wss://your-subdomain.production.google.ekodb.net/ws";
const wsClient = await client.websocket(wsUrl);
// Subscribe to collection changes
const results = await wsClient.findAll("users");
// Process real-time updates
for (const record of results) {
console.log("New/Updated record:", record);
}
await wsClient.close();
// Connect to WebSocket
const wsUrl = "wss://your-subdomain.production.google.ekodb.net/ws";
const wsClient = await client.websocket(wsUrl);
// Subscribe to collection changes
const results = await wsClient.findAll("users");
// Process real-time updates
for (const record of results) {
console.log("New/Updated record:", record);
}
await wsClient.close();
// Connect to WebSocket
val wsUrl = "wss://your-subdomain.production.google.ekodb.net/ws"
val wsClient = client.websocket(wsUrl)
// Subscribe to collection changes
val results = wsClient.findAll("users")
// Process real-time updates
results.forEach { record ->
println("New/Updated record: $record")
}
wsClient.close()
// Connect to WebSocket
wsURL := "wss://your-subdomain.production.google.ekodb.net/ws"
wsClient, err := client.WebSocket(wsURL)
// Subscribe to collection changes
results, err := wsClient.FindAll("users")
// Process real-time updates
for _, record := range results {
fmt.Printf("New/Updated record: %+v\n", record)
}
wsClient.Close()
TTL (Time-To-Live)
Set automatic expiration for documents:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
// Insert with 1 hour TTL
let mut session = Record::new();
session.insert("user_id", "user-123");
session.insert("token", "abc123");
let result = client.insert_with_ttl(
"sessions",
session,
"1h" // Expires in 1 hour
).await?;
# Insert with 1 hour TTL
session = {
"user_id": "user-123",
"token": "abc123"
}
result = client.insert_with_ttl(
"sessions",
session,
ttl="1h" # Expires in 1 hour
)
// Insert with 1 hour TTL
const session = {
userId: "user-123",
token: "abc123"
};
const result = await client.insertWithTTL(
"sessions",
session,
"1h" // Expires in 1 hour
);
// Insert with 1 hour TTL
const session = {
userId: "user-123",
token: "abc123"
};
const result = await client.insertWithTTL(
"sessions",
session,
"1h" // Expires in 1 hour
);
// Insert with 1 hour TTL
val session = Record.new()
.insert("user_id", "user-123")
.insert("token", "abc123")
val result = client.insertWithTTL(
"sessions",
session,
ttl = "1h" // Expires in 1 hour
)
// Insert with 1 hour TTL
session := ekodb.Record{
"user_id": "user-123",
"token": "abc123",
}
result, err := client.Insert("sessions", session, "1h") // Expires in 1 hour
Functions
Functions are ekoDB's stored procedures system that runs on the server. They can be called from any client library or via REST API to execute complex business logic, queries, CRUD operations, AI workflows, and batch processing.
Functions let you create, store, and execute complete business logic as composable operations. Define your data logic once in ekoDB, then call it like puzzle pieces from any client.
What You Can Do
- ✅ Complete business logic - Queries, CRUD, AI operations in one place
- ✅ Parameterize everything - Dynamic values via
{{param_name}} - ✅ Version control - Track function versions
- ✅ Compose like puzzles - Chain operations together
- ✅ Call from anywhere - REST API or any client library
Function Capabilities
- Query Operations: Find, filter, search, vector search, hybrid search
- CRUD Operations: Insert, update, delete (single and batch)
- Transformations: Group, project, count
- AI Operations: Chat completions, embeddings generation
- Conditional Logic: If/then/else, foreach loops
- External Integrations: HTTP requests to any REST API
Basic Example
Create a function to query active users:
POST /api/functions
Content-Type: application/json
{
"label": "get_active_users",
"name": "Get Active Users",
"description": "Returns active users with a limit",
"version": "1.0",
"parameters": {
"limit": {
"default": 10,
"required": false
}
},
"functions": [
{
"type": "Query",
"collection": "users",
"filter": {
"type": "Condition",
"field": "status",
"operator": "Eq",
"value": "active"
},
"limit": "{{limit}}"
}
]
}
Call a Function
Execute via REST API:
POST /api/functions/get_active_users
Content-Type: application/json
{
"limit": 20
}
Managing Functions
# List all functions
GET /api/functions
# Get a specific function
GET /api/functions/get_active_users
# Update a function
PUT /api/functions/{id}
# Delete a function
DELETE /api/functions/get_active_users
Parameters
Make functions dynamic with parameters:
{
"parameters": {
"status": {
"default": "active",
"required": false,
"description": "Filter by status"
},
"min_amount": {
"required": true,
"description": "Minimum amount"
}
}
}
Reference parameters in your function definitions using {{param_name}}:
{
"type": "Query",
"collection": "orders",
"filter": {
"type": "Condition",
"field": "status",
"operator": "Eq",
"value": "{{status}}"
}
}
Available Operations
Functions support these operation types:
Query Operations
FindAll- Retrieve all recordsQuery- Advanced filtering, sorting, paginationVectorSearch- Semantic similarity searchHybridSearch- Combine text + vector searchTextSearch- Full-text searchFindById- Get specific record by IDFindOne- Find one by key/value
CRUD Operations
Insert- Insert single recordBatchInsert- Insert multiple recordsUpdate- Update with filterUpdateById- Update specific recordDelete- Delete with filterDeleteById- Delete specific recordBatchDelete- Delete multiple records
Transformations
Group- Group and aggregateProject- Select/exclude fieldsCount- Count records
AI Operations
Chat- AI chat completionsEmbed- Generate embeddings
Logic & Control
If- Conditional executionForEach- Loop over recordsCallFunction- Call another function
External Integrations
HttpRequest- Call external APIs (Stripe, SendGrid, etc.)
Example: AI-Powered Search
Combine embeddings with search:
{
"label": "smart_search",
"name": "Smart Product Search",
"parameters": {
"query": { "required": true }
},
"functions": [
{
"type": "Embed",
"input_field": "query",
"output_field": "query_embedding"
},
{
"type": "HybridSearch",
"collection": "products",
"query_text": "{{query}}",
"query_vector": "{{query_embedding}}",
"limit": 10
}
]
}
Example: Batch Processing
Process multiple records with AI:
{
"label": "enrich_articles",
"name": "AI Content Enrichment",
"functions": [
{
"type": "Query",
"collection": "articles",
"filter": {
"type": "Condition",
"field": "embedding",
"operator": "Eq",
"value": null
},
"limit": 100
},
{
"type": "ForEach",
"functions": [
{
"type": "Embed",
"input_field": "content",
"output_field": "embedding"
},
{
"type": "UpdateById",
"collection": "articles",
"record_id": "{{id}}",
"updates": {
"embedding": "{{embedding}}"
}
}
]
}
]
}
Best Practices
- Keep it simple - Start with single operations, build up
- Use parameters - Make functions reusable with dynamic values
- Filter early - Reduce data before expensive operations
- Add descriptions - Document what each function does
- Tag for organization - Use tags like
analytics,users,ai - Version your functions - Track changes with version field
- Test thoroughly - Validate with edge cases
Storage
Functions are stored in a dedicated collection: functions_{db_name} (configurable)
Complete Documentation
For complete details including:
- All operation types and parameters
- Advanced parameter resolution
- Conditional logic patterns
- External API integration examples
- Error handling
See the Functions GitHub Examples with working code in all 6 languages.
Next Steps
- GitHub Examples - 105 working examples across all 6 languages
- API Reference - Direct HTTP API documentation
Need Help?
- 📧 Email: support@ekodb.io
- 🐛 Issues: GitHub Issues
- 📖 Documentation: docs.ekodb.io