Basic Operations
This guide covers the essential CRUD (Create, Read, Update, Delete) operations using ekoDB client libraries.
:::tip Complete Examples Available For complete, runnable examples, visit the ekoDB Examples Repository. It contains 93 examples (56 client library + 37 direct API examples). :::
Prerequisites
Before you begin, make sure you have:
Client Initialization
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
use ekodb_client::Client;
let client = Client::builder()
.base_url("https://your-subdomain.production.google.ekodb.net")
.api_key("your-api-key")
.build()?;
from ekodb_client import Client
client = Client.new(
"https://your-subdomain.production.google.ekodb.net",
"your-api-key"
)
import { EkoDBClient } from "@ekodb/ekodb-client";
const client = new EkoDBClient({
baseURL: "https://your-subdomain.production.google.ekodb.net",
apiKey: "your-api-key"
});
await client.init();
const { EkoDBClient } = require("@ekodb/ekodb-client");
const client = new EkoDBClient({
baseURL: "https://your-subdomain.production.google.ekodb.net",
apiKey: "your-api-key"
});
await client.init();
import io.ekodb.client.EkoDBClient
val client = EkoDBClient.Builder()
.baseUrl("https://your-subdomain.production.google.ekodb.net")
.apiKey("your-api-key")
.build()
import "github.com/ekoDB/ekodb-client-go"
client := ekodb.NewClient(
"https://your-subdomain.production.google.ekodb.net",
"your-api-key",
)
Insert Records
Create new records in a collection:
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
use ekodb_client::Record;
let mut user = Record::new();
user.insert("name", "Alice Smith");
user.insert("email", "alice@example.com");
user.insert("age", 28);
let result = client.insert("users", user).await?;
println!("Created user with ID: {:?}", result.get("id"));
user = {
"name": "Alice Smith",
"email": "alice@example.com",
"age": 28
}
result = await client.insert("users", user)
print(f"Created user with ID: {result['id']}")
const user = {
name: "Alice Smith",
email: "alice@example.com",
age: 28
};
const result = await client.insert("users", user);
console.log(`Created user with ID: ${result.id}`);
const user = {
name: "Alice Smith",
email: "alice@example.com",
age: 28
};
const result = await client.insert("users", user);
console.log(`Created user with ID: ${result.id}`);
import io.ekodb.client.types.Record
val user = Record.new()
.insert("name", "Alice Smith")
.insert("email", "alice@example.com")
.insert("age", 28)
val result = client.insert("users", user)
println("Created user with ID: ${result["id"]}")
user := map[string]interface{}{
"name": "Alice Smith",
"email": "alice@example.com",
"age": 28,
}
result, err := client.Insert("users", user)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created user with ID: %s\n", result["id"])
Find Records
Find by ID
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let user = client.find_by_id("users", "user-id-123").await?;
println!("Found user: {:?}", user);
user = await client.find_by_id("users", "user-id-123")
print(f"Found user: {user}")
const user = await client.findById("users", "user-id-123");
console.log("Found user:", user);
const user = await client.findById("users", "user-id-123");
console.log("Found user:", user);
val user = client.findById("users", "user-id-123")
println("Found user: $user")
user, err := client.FindByID("users", "user-id-123")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found user: %+v\n", user)
Find All Records
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let users = client.find_all("users").await?;
println!("Found {} users", users.len());
users = await client.find("users", limit=100)
print(f"Found {len(users)} users")
const users = await client.find("users", { limit: 100 });
console.log(`Found ${users.length} users`);
const users = await client.find("users", { limit: 100 });
console.log(`Found ${users.length} users`);
val users = client.find("users", limit = 100)
println("Found ${users.size} users")
users, err := client.Find("users", map[string]interface{}{"limit": 100})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d users\n", len(users))
Update Records
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let mut updates = Record::new();
updates.insert("age", 29);
updates.insert("email", "alice.smith@example.com");
let updated = client.update("users", "user-id-123", updates).await?;
println!("Updated user: {:?}", updated);
updates = {
"age": 29,
"email": "alice.smith@example.com"
}
updated = await client.update("users", "user-id-123", updates)
print(f"Updated user: {updated}")
const updates = {
age: 29,
email: "alice.smith@example.com"
};
const updated = await client.update("users", "user-id-123", updates);
console.log("Updated user:", updated);
const updates = {
age: 29,
email: "alice.smith@example.com"
};
const updated = await client.update("users", "user-id-123", updates);
console.log("Updated user:", updated);
val updates = Record.new()
.insert("age", 29)
.insert("email", "alice.smith@example.com")
val updated = client.update("users", "user-id-123", updates)
println("Updated user: $updated")
updates := map[string]interface{}{
"age": 29,
"email": "alice.smith@example.com",
}
updated, err := client.Update("users", "user-id-123", updates)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Updated user: %+v\n", updated)
Delete Records
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
client.delete("users", "user-id-123").await?;
println!("User deleted successfully");
await client.delete("users", "user-id-123")
print("User deleted successfully")
await client.delete("users", "user-id-123");
console.log("User deleted successfully");
await client.delete("users", "user-id-123");
console.log("User deleted successfully");
client.delete("users", "user-id-123")
println("User deleted successfully")
err := client.Delete("users", "user-id-123")
if err != nil {
log.Fatal(err)
}
fmt.Println("User deleted successfully")
Convenience Methods
:::tip New in v0.8.0 These ergonomic helper methods simplify common patterns and reduce boilerplate code. :::
Upsert (Insert or Update)
Atomic insert-or-update operation. Attempts to update the record first; if it doesn't exist, it inserts it instead.
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
use ekodb_client::Record;
let mut user = Record::new();
user.insert("name", "Alice Smith");
user.insert("email", "alice@example.com");
user.insert("age", 29);
// Will update if exists, insert if not
let result = client.upsert("users", "user-123", user, None).await?;
println!("Upserted user: {:?}", result);
user = {
"name": "Alice Smith",
"email": "alice@example.com",
"age": 29
}
# Will update if exists, insert if not
result = await client.upsert("users", "user-123", user)
print(f"Upserted user: {result}")
const user = {
name: "Alice Smith",
email: "alice@example.com",
age: 29
};
// Will update if exists, insert if not
const result = await client.upsert("users", "user-123", user);
console.log("Upserted user:", result);
const user = {
name: "Alice Smith",
email: "alice@example.com",
age: 29
};
// Will update if exists, insert if not
const result = await client.upsert("users", "user-123", user);
console.log("Upserted user:", result);
import io.ekodb.client.types.Record
val user = Record.new()
.insert("name", "Alice Smith")
.insert("email", "alice@example.com")
.insert("age", 29)
// Will update if exists, insert if not
val result = client.upsert("users", "user-123", user)
println("Upserted user: $result")
user := map[string]interface{}{
"name": "Alice Smith",
"email": "alice@example.com",
"age": 29,
}
// Will update if exists, insert if not
result, err := client.Upsert("users", "user-123", user)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Upserted user: %+v\n", result)
Find One Record by Field
Find a single record matching a specific field value. Returns null/nil/None if no match found.
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
// Find user by email
let user = client.find_one("users", "email", "alice@example.com").await?;
match user {
Some(record) => println!("Found user: {:?}", record),
None => println!("User not found"),
}
# Find user by email
user = await client.find_one("users", "email", "alice@example.com")
if user:
print(f"Found user: {user}")
else:
print("User not found")
// Find user by email
const user = await client.findOne("users", "email", "alice@example.com");
if (user) {
console.log("Found user:", user);
} else {
console.log("User not found");
}
// Find user by email
const user = await client.findOne("users", "email", "alice@example.com");
if (user) {
console.log("Found user:", user);
} else {
console.log("User not found");
}
// Find user by email
val user = client.findOne("users", "email", "alice@example.com")
if (user != null) {
println("Found user: $user")
} else {
println("User not found")
}
// Find user by email
user, err := client.FindOne("users", "email", "alice@example.com")
if err != nil {
log.Fatal(err)
}
if user != nil {
fmt.Printf("Found user: %+v\n", user)
} else {
fmt.Println("User not found")
}
Check Record Existence
Efficiently check if a record exists without fetching the full document.
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
if client.exists("users", "user-123").await? {
println!("User exists");
} else {
println!("User not found");
}
if await client.exists("users", "user-123"):
print("User exists")
else:
print("User not found")
if (await client.exists("users", "user-123")) {
console.log("User exists");
} else {
console.log("User not found");
}
if (await client.exists("users", "user-123")) {
console.log("User exists");
} else {
console.log("User not found");
}
if (client.exists("users", "user-123")) {
println("User exists")
} else {
println("User not found")
}
exists, err := client.Exists("users", "user-123")
if err != nil {
log.Fatal(err)
}
if exists {
fmt.Println("User exists")
} else {
fmt.Println("User not found")
}
Paginate Results
Simplified pagination using page numbers (1-indexed) instead of skip/limit calculations.
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
// Get page 2 with 10 records per page
let page = 2;
let page_size = 10;
let users = client.paginate("users", page, page_size).await?;
println!("Found {} users on page {}", users.len(), page);
# Get page 2 with 10 records per page
page = 2
page_size = 10
users = await client.paginate("users", page, page_size)
print(f"Found {len(users)} users on page {page}")
// Get page 2 with 10 records per page
const page = 2;
const pageSize = 10;
const users = await client.paginate("users", page, pageSize);
console.log(`Found ${users.length} users on page ${page}`);
// Get page 2 with 10 records per page
const page = 2;
const pageSize = 10;
const users = await client.paginate("users", page, pageSize);
console.log(`Found ${users.length} users on page ${page}`);
// Get page 2 with 10 records per page
val page = 2
val pageSize = 10
val users = client.paginate("users", page, pageSize)
println("Found ${users.size} users on page $page")
// Get page 2 with 10 records per page
page := 2
pageSize := 10
users, err := client.Paginate("users", page, pageSize)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found %d users on page %d\n", len(users), page)
:::tip Why Use Convenience Methods?
- Upsert: Eliminates need for exists-check-then-insert patterns
- FindOne: Cleaner than building a query with
limit(1) - Exists: More efficient than fetching the full record
- Paginate: No need to calculate skip/offset manually :::
Collection Management
List Collections
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let collections = client.list_collections().await?;
println!("Collections: {:?}", collections);
collections = await client.list_collections()
print(f"Collections: {collections}")
const collections = await client.listCollections();
console.log("Collections:", collections);
const collections = await client.listCollections();
console.log("Collections:", collections);
val collections = client.listCollections()
println("Collections: $collections")
collections, err := client.ListCollections()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Collections: %v\n", collections)
Delete Collection
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
client.delete_collection("old_data").await?;
println!("Collection deleted");
await client.delete_collection("old_data")
print("Collection deleted")
await client.deleteCollection("old_data");
console.log("Collection deleted");
await client.deleteCollection("old_data");
console.log("Collection deleted");
client.deleteCollection("old_data")
println("Collection deleted")
err := client.DeleteCollection("old_data")
if err != nil {
log.Fatal(err)
}
fmt.Println("Collection deleted")
Check Collection Exists
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let exists = client.collection_exists("users").await?;
if exists {
println!("Collection exists");
}
exists = await client.collection_exists("users")
if exists:
print("Collection exists")
const exists = await client.collectionExists("users");
if (exists) {
console.log("Collection exists");
}
const exists = await client.collectionExists("users");
if (exists) {
console.log("Collection exists");
}
val exists = client.collectionExists("users")
if (exists) {
println("Collection exists")
}
exists, err := client.CollectionExists("users")
if err != nil {
log.Fatal(err)
}
if exists {
fmt.Println("Collection exists")
}
Count Documents
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
let count = client.count_documents("users").await?;
println!("Total documents: {}", count);
count = await client.count_documents("users")
print(f"Total documents: {count}")
const count = await client.countDocuments("users");
console.log(`Total documents: ${count}`);
const count = await client.countDocuments("users");
console.log(`Total documents: ${count}`);
val count = client.count("users")
println("Total documents: $count")
count, err := client.CountDocuments("users")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Total documents: %d\n", count)
Restore from Trash
Restore deleted records from trash. Records remain in trash for 30 days before permanent deletion.
- 🦀 Rust
- 🐍 Python
- 📘 TypeScript
- 📦 JavaScript
- 🟣 Kotlin
- 🔷 Go
// Restore single record
let restored = client.restore_deleted("users", "record_id_123").await?;
if restored {
println!("Record restored successfully");
}
// Restore all records in collection
let count = client.restore_collection("users").await?;
println!("Restored {} records", count);
# Restore single record
restored = await client.restore_deleted("users", "record_id_123")
if restored:
print("Record restored successfully")
// Restore single record
const restored = await client.restoreRecord("users", "record_id_123");
console.log("Record restored:", restored);
// Restore all records in collection
const result = await client.restoreCollection("users");
console.log(`Restored ${result.recordsRestored} records`);
// Restore single record
const restored = await client.restoreRecord("users", "record_id_123");
console.log("Record restored:", restored);
// Restore all records in collection
const result = await client.restoreCollection("users");
console.log(`Restored ${result.recordsRestored} records`);
// Use REST API directly for restore operations
val response = httpClient.post("$baseUrl/api/trash/users/record_id_123") {
header("Authorization", "Bearer $token")
}
// Restore single record
err := client.RestoreRecord("users", "record_id_123")
if err != nil {
log.Fatal(err)
}
// Restore all records in collection
count, err := client.RestoreCollection("users")
fmt.Printf("Restored %d records\n", count)
:::tip Trash Retention All client libraries support restore operations. Deleted records are kept in trash for 30 days before permanent deletion. :::
Complete Examples
For complete, runnable examples with error handling and advanced features, visit:
📚 Example Repository
ekoDB Client Examples
The repository contains 93 examples total (56 client library + 37 direct API) organized by language:
- Rust Examples - 15 client examples + 10 direct API examples
- Python Examples - 16 client examples + 10 direct API examples
- TypeScript Examples - 16 client examples (Node.js & browsers)
- Go Examples - 15 client examples + 10 direct API examples
- Kotlin Examples - 15 client examples with coroutines
- JavaScript Examples - 12 client examples + 10 direct API examples for Node.js
Featured Examples
Core Operations:
- Simple CRUD - Basic create, read, update, delete operations
- Query Builder - Complex queries with filters, sorting, pagination
- Batch Operations - Efficient bulk inserts, updates, deletes
- Schema Management - Define and enforce data schemas
New in v0.8.0:
- Convenience Methods - Upsert, findOne, exists, paginate examples (all languages)
- Bypass Ripple - Control ripple propagation in multi-node deployments (all languages)
Advanced Features:
- Search - Full-text search with scoring
- WebSocket - Real-time queries and subscriptions
- TTL - Automatic document expiration
- Key-Value - Simple key-value store operations
- Chat & RAG - Conversational AI with retrieval-augmented generation
- Functions - Server-side function execution
Running Examples
Visit the ekoDB Examples Repository for complete, runnable examples in all supported languages. Each example can be copied and adapted to your own project.
- Rust Examples
- Python Examples
- TypeScript/JavaScript Examples
- Kotlin Examples
- Go Examples
Next Steps
- More Examples - Query builder, search, batch operations, and more
- API Reference - Direct HTTP API documentation
- Authentication - Learn about API keys and permissions
Need Help?
- 💬 Support: app.ekodb.io/support
- 📧 Email: support@ekodb.io