Syntax · 5 of 6
for / in loops
Iterate over an array — typically a find result. The loop body runs once per element with var bound to the current item.
Basic shape
for item in collection_or_array {
// body — has access to `item`
}
Iterating a find result
proc deactivate_stale(days) {
let users = find("users", {last_seen_days: {$gte: days}})
for u in users {
update("users", {_id: u._id}, {$set: {active: false}})
}
return {deactivated: count("users", {active: false})}
}
Iterating a literal array
proc seed_categories() {
let cats = ["electronics", "books", "clothing", "food"]
for c in cats {
insert("categories", {name: c, created_at: "now"})
}
return {seeded: 4}
}
Filter then loop
proc flag_low_stock(threshold) {
let lows = find("products", {stock: {$lt: threshold}})
for p in lows {
update("products", {sku: p.sku}, {$set: {needs_restock: true}})
insert("reorder_queue", {sku: p.sku, current: p.stock})
}
return {flagged: count("reorder_queue")}
}
Conditional inside the loop
proc charge_subscriptions() {
let due = find("subscriptions", {status: "active", due: true})
for sub in due {
let user = find_one("users", {_id: sub.user_id})
if user.balance >= sub.price {
update("users", {_id: sub.user_id}, {$inc: {balance: -sub.price}})
insert("charges", {sub_id: sub._id, amount: sub.price, status: "ok"})
} else {
update("subscriptions", {_id: sub._id}, {$set: {status: "past_due"}})
insert("charges", {sub_id: sub._id, amount: sub.price, status: "failed"})
}
}
return {processed: count("charges")}
}
Nested loops
proc fanout_notifications(group_id, message) {
let members = find("group_members", {group_id: group_id})
for m in members {
let devices = find("devices", {user_id: m.user_id})
for d in devices {
insert("notifications", {
device_id: d._id,
user_id: m.user_id,
message: message,
status: "queued"
})
}
}
return {ok: true}
}
Aggregating in a loop
Sometimes aggregate is cleaner — but a loop works fine for small result sets.
proc total_owed(account_id) {
let invoices = find("invoices", {account_id: account_id, status: "open"})
let sum = 0
for i in invoices {
sum = sum + i.amount
}
return {account_id: account_id, owed: sum}
}
Performance tip: if your loop touches the same document many times, prefer one
update with an array of $inc/$set fields over many small ones. OCC validates a version per document, not per field.