Collections
Work with collections of JSON documents
Overview
Collections store JSON documents. Each document must be a JSON object and will be assigned a unique _id field if one isn't provided. Collections are created automatically when you first access them.
Insert Documents
Insert a single document into a collection. Returns the document ID:
use serde_json::json;
let users = db.collection("users");
let id = users.insert(json!({
"name": "Alice",
"email": "alice@example.com",
"age": 30
}))?;
println!("Inserted: {}", id);
coll = db.get_collection("users")
doc_id = coll.insert({
"name": "Alice",
"email": "alice@example.com",
"age": 30
})
print(f"Inserted: {doc_id}")
const users = db.collection('users');
const id = await users.insert({
name: 'Alice',
email: 'alice@example.com',
age: 30
});
console.log('Inserted:', id);
users := db.Collection("users")
id, err := users.Insert(map[string]interface{}{
"name": "Alice",
"email": "alice@example.com",
"age": 30,
})
fmt.Printf("Inserted: %s\n", id)
Insert Many
Insert multiple documents at once. Much more efficient than individual inserts:
let docs = vec![
json!({"name": "Alice", "age": 30}),
json!({"name": "Bob", "age": 25}),
json!({"name": "Charlie", "age": 35}),
];
let ids = users.insert_many(docs)?;
println!("Inserted {} documents", ids.len());
docs = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35}
]
ids = coll.insert_many(docs)
print(f"Inserted {len(ids)} documents")
const docs = [
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 },
{ name: 'Charlie', age: 35 }
];
const ids = await users.insertMany(docs);
console.log(`Inserted ${ids.length} documents`);
docs := []map[string]interface{}{
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35},
}
ids, err := users.InsertMany(docs)
fmt.Printf("Inserted %d documents\n", len(ids))
Find Documents
Find by ID
Retrieve a document by its unique ID:
let user = users.find_by_id(&id)?;
println!("Name: {}", user["name"]);
user = coll.find_by_id(doc_id)
if user:
print(f"Name: {user['name']}")
const user = await users.findById(id);
console.log('Name:', user.name);
user, err := users.FindByID(id)
fmt.Printf("Name: %s\n", user["name"])
Find All
Retrieve all documents in a collection:
let all_users = users.find_all()?;
for user in all_users {
println!("{}: {}", user["name"], user["age"]);
}
all_users = coll.find_all()
for user in all_users:
print(f"{user['name']}: {user['age']}")
const allUsers = await users.findAll();
allUsers.forEach(user => {
console.log(`${user.name}: ${user.age}`);
});
allUsers, err := users.FindAll()
for _, user := range allUsers {
fmt.Printf("%s: %v\n", user["name"], user["age"])
}
Find with Query
Query documents using the query language. See the Query Language guide for full syntax:
// Find users over 25 in NYC
let results = users.find("age > 25 and city is 'NYC'")?;
// Find with OR condition
let results = users.find("age < 18 or age > 65")?;
// Find with field existence check
let results = users.find("email")?;
# Find users over 25 in NYC
results = coll.find("age > 25 and city = 'NYC'")
# Find with OR condition
results = coll.find("age < 18 or age > 65")
# Find with field existence check
results = coll.find("email")
// Find users over 25 in NYC
const results = await users.find("age > 25 and city is 'NYC'");
// Find with OR condition
const results = await users.find("age < 18 or age > 65");
// Find with field existence check
const results = await users.find("email");
// Find users over 25 in NYC
results, err := users.Find("age > 25 and city is 'NYC'")
// Find with OR condition
results, err := users.Find("age < 18 or age > 65")
// Find with field existence check
results, err := users.Find("email")
Find One
Find the first document matching a query:
let user = users.find_one("email is 'alice@example.com'")?;
if let Some(u) = user {
println!("Found: {}", u["name"]);
}
user = coll.find_one("email = 'alice@example.com'")
if user:
print(f"Found: {user['name']}")
const user = await users.findOne("email is 'alice@example.com'");
if (user) {
console.log('Found:', user.name);
}
user, err := users.FindOne("email is 'alice@example.com'")
if user != nil {
fmt.Printf("Found: %s\n", user["name"])
}
Update Documents
Update by ID
Update a document by its ID. Fields are merged - only specified fields are updated:
users.update_by_id(&id, json!({
"age": 31,
"city": "SF"
}))?;
coll.update_by_id(doc_id, {
"age": 31,
"city": "SF"
})
await users.updateById(id, {
age: 31,
city: 'SF'
});
err := users.UpdateByID(id, map[string]interface{}{
"age": 31,
"city": "SF",
})
Update Many
Update all documents matching a query. Returns the count of updated documents:
let count = users.update("age >= 18", json!({
"status": "adult"
}))?;
println!("Updated {} documents", count);
count = coll.update("age >= 18", {
"status": "adult"
})
print(f"Updated {count} documents")
const count = await users.update("age >= 18", {
status: 'adult'
});
console.log(`Updated ${count} documents`);
count, err := users.Update("age >= 18", map[string]interface{}{
"status": "adult",
})
fmt.Printf("Updated %d documents\n", count)
Update One
Update only the first document matching a query:
let updated = users.update_one("name is 'Alice'", json!({
"verified": true
}))?;
println!("Updated: {}", updated);
updated = coll.update_one("name = 'Alice'", {
"verified": True
})
print(f"Updated: {updated}")
const updated = await users.updateOne("name is 'Alice'", {
verified: true
});
console.log('Updated:', updated);
updated, err := users.UpdateOne("name is 'Alice'", map[string]interface{}{
"verified": true,
})
fmt.Printf("Updated: %v\n", updated)
Upsert
Insert or update a document. If the document exists, update it; otherwise, insert it:
// Upsert by ID
let id = users.upsert_by_id("user_123", json!({
"name": "Alice",
"age": 30
}))?;
// Upsert by query
let id = users.upsert("email is 'alice@example.com'", json!({
"name": "Alice",
"email": "alice@example.com",
"age": 30
}))?;
# Upsert by ID
doc_id = coll.upsert_by_id("user_123", {
"name": "Alice",
"age": 30
})
# Upsert by query
doc_id = coll.upsert("email = 'alice@example.com'", {
"name": "Alice",
"email": "alice@example.com",
"age": 30
})
// Upsert by ID
const id = await users.upsertById('user_123', {
name: 'Alice',
age: 30
});
// Upsert by query
const id = await users.upsert("email is 'alice@example.com'", {
name: 'Alice',
email: 'alice@example.com',
age: 30
});
// Upsert by ID
id, err := users.UpsertByID("user_123", map[string]interface{}{
"name": "Alice",
"age": 30,
})
// Upsert by query
id, err := users.Upsert("email is 'alice@example.com'", map[string]interface{}{
"name": "Alice",
"email": "alice@example.com",
"age": 30,
})
Delete Documents
Delete by ID
Delete a document by its unique ID:
users.delete_by_id(&id)?;
coll.delete_by_id(doc_id)
await users.deleteById(id);
err := users.DeleteByID(id)
Delete Many
Delete all documents matching a query. Returns the count of deleted documents:
let count = users.delete("age < 18")?;
println!("Deleted {} documents", count);
count = coll.delete("age < 18")
print(f"Deleted {count} documents")
const count = await users.delete("age < 18");
console.log(`Deleted ${count} documents`);
count, err := users.Delete("age < 18")
fmt.Printf("Deleted %d documents\n", count)
Delete One
Delete only the first document matching a query:
let deleted = users.delete_one("email is 'old@example.com'")?;
println!("Deleted: {}", deleted);
deleted = coll.delete_one("email = 'old@example.com'")
print(f"Deleted: {deleted}")
const deleted = await users.deleteOne("email is 'old@example.com'");
console.log('Deleted:', deleted);
deleted, err := users.DeleteOne("email is 'old@example.com'")
fmt.Printf("Deleted: %v\n", deleted)
Count Documents
Count all documents or documents matching a query:
// Count all documents
let total = users.count()?;
// Count with query
let adults = users.count_with_query("age >= 18")?;
println!("Total: {}, Adults: {}", total, adults);
# Count all documents
total = coll.count()
# Count with query
adults = coll.count_with_query("age >= 18")
print(f"Total: {total}, Adults: {adults}")
// Count all documents
const total = await users.count();
// Count with query
const adults = await users.countWithQuery("age >= 18");
console.log(`Total: ${total}, Adults: ${adults}`);
// Count all documents
total, err := users.Count()
// Count with query
adults, err := users.CountWithQuery("age >= 18")
fmt.Printf("Total: %d, Adults: %d\n", total, adults)
Advanced Query Options
Query with sorting, pagination, and field projection:
let options = QueryOptions {
filter: Some("age > 18".to_string()),
sort_field: Some("name".to_string()),
sort_asc: true,
limit: 10,
skip: 0,
project_fields: Some(vec!["name".to_string(), "email".to_string()]),
exclude_fields: Some(vec!["_internal".to_string()]),
};
let results = users.query_with_options(options)?;
results = coll.query_with_options(
filter_str="age > 18",
sort_field="name",
sort_asc=True,
limit=10,
skip=0,
project_fields=["name", "email"],
exclude_fields=["_internal"]
)
const results = await users.queryWithOptions({
filter: "age > 18",
sortField: "name",
sortAsc: true,
limit: 10,
skip: 0,
projectFields: ["name", "email"],
excludeFields: ["_internal"]
});
options := jasonisnthappy.QueryOptions{
Filter: "age > 18",
SortField: "name",
SortAsc: true,
Limit: 10,
Skip: 0,
ProjectFields: []string{"name", "email"},
ExcludeFields: []string{"_internal"},
}
results, err := users.QueryWithOptions(options)
Bulk Operations
Execute multiple operations in a single transaction for better performance:
let operations = vec![
BulkOperation::Insert {
doc: json!({"name": "Alice"}),
},
BulkOperation::UpdateOne {
filter: "name is 'Bob'".to_string(),
update: json!({"age": 31}),
},
BulkOperation::Delete {
filter: "age < 18".to_string(),
},
];
let result = users.bulk_write(operations, true)?;
println!("Inserted: {}, Updated: {}, Deleted: {}",
result.inserted_count,
result.updated_count,
result.deleted_count
);
result = coll.bulk_write([
{
"op": "insert",
"doc": {"name": "Alice"}
},
{
"op": "update_one",
"filter": "name = 'Bob'",
"update": {"age": 31}
},
{
"op": "delete",
"filter": "age < 18"
}
], ordered=True)
print(f"Inserted: {result['inserted_count']}")
print(f"Updated: {result['updated_count']}")
print(f"Deleted: {result['deleted_count']}")
const result = await users.bulkWrite([
{
op: 'insert',
doc: { name: 'Alice' }
},
{
op: 'updateOne',
filter: "name is 'Bob'",
update: { age: 31 }
},
{
op: 'delete',
filter: 'age < 18'
}
], true);
console.log(`Inserted: ${result.insertedCount}`);
console.log(`Updated: ${result.updatedCount}`);
console.log(`Deleted: ${result.deletedCount}`);
operations := []jasonisnthappy.BulkOperation{
{
Op: "insert",
Doc: map[string]interface{}{"name": "Alice"},
},
{
Op: "update_one",
Filter: "name is 'Bob'",
Update: map[string]interface{}{"age": 31},
},
{
Op: "delete",
Filter: "age < 18",
},
}
result, err := users.BulkWrite(operations, true)
fmt.Printf("Inserted: %d, Updated: %d, Deleted: %d\n",
result.InsertedCount,
result.UpdatedCount,
result.DeletedCount
)
Distinct Values
Get distinct values for a field across all documents:
// Get all distinct ages
let ages = users.distinct("age")?;
println!("Distinct ages: {:?}", ages);
// Count distinct values
let count = users.count_distinct("city")?;
println!("{} unique cities", count);
# Get all distinct ages
ages = coll.distinct("age")
print(f"Distinct ages: {ages}")
# Count distinct values
count = coll.count_distinct("city")
print(f"{count} unique cities")
// Get all distinct ages
const ages = await users.distinct('age');
console.log('Distinct ages:', ages);
// Count distinct values
const count = await users.countDistinct('city');
console.log(`${count} unique cities`);
// Get all distinct ages
ages, err := users.Distinct("age")
fmt.Printf("Distinct ages: %v\n", ages)
// Count distinct values
count, err := users.CountDistinct("city")
fmt.Printf("%d unique cities\n", count)