Update a single document matching a filter.
local count = collection:UpdateOne(filter, update, upsert)
Parameters:
filter (table): Query filterupdate (table): Update operationsupsert (boolean, optional): Create document if not found (default: false)Returns:
number: Number of documents modified (0 or 1)local players = db:Collection("players")
-- Simple update
local updated = players:UpdateOne(
{ steamid = "STEAM_0:1:12345" },
{ ["$set"] = { last_seen = os.time() } }
)
if updated > 0 then
print("Player updated")
else
print("Player not found")
end
-- Update multiple fields
players:UpdateOne(
{ steamid = "STEAM_0:1:12345" },
{
["$set"] = {
last_seen = os.time(),
username = "NewName",
rank = "VIP"
}
}
)
-- Increment a value
players:UpdateOne(
{ steamid = "STEAM_0:1:12345" },
{ ["$inc"] = { credits = 500 } }
)
-- Create document if it doesn't exist, update if it does
players:UpdateOne(
{ steamid = "STEAM_0:1:12345" },
{
["$set"] = {
username = "Player1",
last_seen = os.time()
},
["$setOnInsert"] = {
created_at = os.time(),
level = 1,
credits = 1000
}
},
true -- upsert = true
)
-- Update player when they disconnect
hook.Add("PlayerDisconnect", "SavePlayerOnLeave", function(ply)
local steamid = ply:SteamID()
players:UpdateOne(
{ steamid = steamid },
{
["$set"] = {
last_seen = os.time(),
username = ply:Nick()
},
["$inc"] = {
total_sessions = 1
}
}
)
end)
Update all documents matching a filter - useful for bulk updates.
local count = collection:UpdateMany(filter, update, upsert)
Parameters:
filter (table): Query filterupdate (table): Update operationsupsert (boolean, optional): Create document if none match (default: false)Returns:
number: Number of documents modified-- Update all VIP players
local updated = players:UpdateMany(
{ rank = "VIP" },
{ ["$inc"] = { credits = 1000 } }
)
print("Gave bonus to", updated, "VIP players")
-- Mark old players as inactive
local thirtyDaysAgo = os.time() - (30 * 24 * 60 * 60)
local updated = players:UpdateMany(
{ last_seen = { ["$lt"] = thirtyDaysAgo } },
{ ["$set"] = { active = false } }
)
print("Marked", updated, "players as inactive")
-- Reset daily quests
players:UpdateMany(
{}, -- Empty filter = all documents
{
["$set"] = {
daily_quest_completed = false,
daily_quest_date = os.date("%Y-%m-%d")
}
}
)
-- Daily reset timer
timer.Create("DailyReset", 24 * 60 * 60, 0, function()
-- Reset daily bonuses
local updated = players:UpdateMany(
{},
{
["$set"] = {
daily_bonus_claimed = false,
daily_login_bonus = false
}
}
)
print("Daily reset complete -", updated, "players")
end)
-- Seasonal event
local function StartSummerEvent()
local updated = players:UpdateMany(
{ level = { ["$gte"] = 10 } },
{
["$inc"] = { event_tokens = 50 },
["$set"] = { event_participant = true }
}
)
PrintMessage(HUD_PRINTTALK, "Summer event started! " .. updated .. " players received tokens!")
end
-- Price adjustment
local function UpdateItemPrices(multiplier)
local updated = shopItems:UpdateMany(
{ category = "weapons" },
{
["$mul"] = { price = multiplier }
}
)
print("Updated", updated, "weapon prices")
end
MongoDB provides powerful operators to modify documents:
-- Set field value
{ ["$set"] = { field = value } }
-- Remove field
{ ["$unset"] = { field = "" } }
-- Rename field
{ ["$rename"] = { old_field = "new_field" } }
-- Set only on insert (with upsert)
{ ["$setOnInsert"] = { field = value } }
-- Set to current timestamp
{ ["$currentDate"] = { field = true } }
-- Increment by amount (can be negative)
{ ["$inc"] = { credits = 100 } }
{ ["$inc"] = { credits = -50 } }
-- Multiply
{ ["$mul"] = { price = 1.5 } }
-- Set to minimum value (only if less than current)
{ ["$min"] = { health = 50 } }
-- Set to maximum value (only if greater than current)
{ ["$max"] = { high_score = 1000 } }
-- Add to array
{ ["$push"] = { items = "new_item" } }
-- Add multiple items
{ ["$push"] = { items = { ["$each"] = { "item1", "item2" } } } }
-- Add if doesn't exist (unique)
{ ["$addToSet"] = { tags = "veteran" } }
-- Remove from array
{ ["$pull"] = { items = "unwanted_item" } }
-- Remove first item (-1) or last item (1)
{ ["$pop"] = { items = 1 } } -- Remove last
{ ["$pop"] = { items = -1 } } -- Remove first
-- Add credits
local function AddCredits(ply, amount)
local updated = players:UpdateOne(
{ steamid = ply:SteamID() },
{ ["$inc"] = { credits = amount } }
)
if updated > 0 then
ply:ChatPrint("You received " .. amount .. " credits!")
return true
end
return false
end
-- Remove credits (check if enough first)
local function RemoveCredits(ply, amount)
local updated = players:UpdateOne(
{
steamid = ply:SteamID(),
credits = { ["$gte"] = amount } -- Must have enough
},
{ ["$inc"] = { credits = -amount } }
)
if updated > 0 then
return true
else
ply:ChatPrint("Not enough credits!")
return false
end
end
-- Award achievement
local function AwardAchievement(ply, achievementId)
local updated = players:UpdateOne(
{ steamid = ply:SteamID() },
{
["$addToSet"] = {
achievements = achievementId
},
["$inc"] = {
achievement_points = 10
}
}
)
if updated > 0 then
ply:ChatPrint("Achievement unlocked: " .. achievementId)
-- Give reward
AddCredits(ply, 100)
end
end
-- Add item to inventory
local function AddItemToInventory(steamid, itemId, quantity)
-- Check if item already exists
local inv = inventories:FindOne({
steamid = steamid,
["items.item_id"] = itemId
})
if inv then
-- Item exists - increment quantity
inventories:UpdateOne(
{
steamid = steamid,
["items.item_id"] = itemId
},
{
["$inc"] = { ["items.$.quantity"] = quantity }
}
)
else
-- New item - add to array
inventories:UpdateOne(
{ steamid = steamid },
{
["$push"] = {
items = {
item_id = itemId,
quantity = quantity,
added_at = os.time()
}
}
}
)
end
end
-- Level up player
local function LevelUp(ply)
local updated = players:UpdateOne(
{ steamid = ply:SteamID() },
{
["$inc"] = {
level = 1,
skill_points = 5
},
["$push"] = {
level_history = {
level = ply.Level + 1,
timestamp = os.time()
}
}
}
)
if updated > 0 then
ply:ChatPrint("Level Up! You are now level " .. (ply.Level + 1))
ply:ChatPrint("You received 5 skill points!")
end
end
Update only if conditions are met:
-- Purchase item only if player has enough money
local function BuyItem(ply, itemId, price)
local updated = players:UpdateOne(
{
steamid = ply:SteamID(),
credits = { ["$gte"] = price } -- Condition
},
{
["$inc"] = { credits = -price },
["$push"] = { purchases = itemId }
}
)
if updated > 0 then
ply:ChatPrint("Purchase successful!")
return true
else
ply:ChatPrint("Not enough credits!")
return false
end
end
-- DON'T: Race condition possible
local player = players:FindOne({ steamid = steamid })
player.credits = player.credits + 100
players:UpdateOne({ steamid = steamid }, { ["$set"] = player })
-- DO: Atomic operation
players:UpdateOne(
{ steamid = steamid },
{ ["$inc"] = { credits = 100 } }
)