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)