CRUD Operations
Query Operations
Find and retrieve documents from MongoDB
Query Operations
Learn how to find and retrieve documents from MongoDB collections.
Find
Retrieve multiple documents matching a filter.
Syntax
local documents = collection:Find(filter [, limit])
Parameters
filter(table): Query filter (empty{}for all documents)limit(number, optional): Maximum number of documents to return
Returns
table: Array of matching documentsnil: On failure
Examples
local players = db:Collection("players")
-- Find all documents
local allPlayers = players:Find({})
print("Total players:", #allPlayers)
-- Find with filter
local highLevel = players:Find({
level = { ["$gte"] = 10 }
})
-- Find with limit
local topPlayers = players:Find(
{ level = { ["$gte"] = 5 } },
10 -- Return max 10 documents
)
-- Iterate results
for i, player in ipairs(allPlayers) do
print(player.username, "- Level", player.level)
end
FindOne
Retrieve the first document matching a filter.
Syntax
local document = collection:FindOne(filter)
Parameters
filter(table): Query filter
Returns
table: First matching documentnil: If not found or on failure
Examples
local players = db:Collection("players")
-- Find by unique field
local player = players:FindOne({
steamid = "STEAM_0:1:12345678"
})
if player then
print("Found:", player.username)
print("Level:", player.level)
print("Credits:", player.credits)
else
print("Player not found")
end
-- Find by multiple criteria
local vipPlayer = players:FindOne({
level = { ["$gte"] = 50 },
vip = true
})
Count
Count documents matching a filter.
Syntax
local count = collection:Count(filter)
Parameters
filter(table): Query filter (empty{}for all documents)
Returns
number: Count of matching documents
Examples
local players = db:Collection("players")
-- Count all documents
local totalPlayers = players:Count({})
print("Total players:", totalPlayers)
-- Count with filter
local activePlayers = players:Count({
last_login = { ["$gte"] = os.time() - (7 * 24 * 60 * 60) }
})
print("Active players (7 days):", activePlayers)
-- Count by criteria
local vipCount = players:Count({ vip = true })
local warriorCount = players:Count({ class = "Warrior" })
Query Filters
Empty Filter (All Documents)
-- Get all documents
local all = collection:Find({})
Equality
-- Exact match
local warriors = players:Find({ class = "Warrior" })
-- Match specific value
local level10 = players:Find({ level = 10 })
Comparison Operators
-- Greater than
local high = players:Find({ level = { ["$gt"] = 10 } })
-- Greater than or equal
local medium = players:Find({ level = { ["$gte"] = 5 } })
-- Less than
local low = players:Find({ level = { ["$lt"] = 5 } })
-- Less than or equal
local starter = players:Find({ level = { ["$lte"] = 3 } })
-- Not equal
local notBanned = players:Find({ banned = { ["$ne"] = true } })
-- Range (combined)
local midRange = players:Find({
level = { ["$gte"] = 10, ["$lte"] = 20 }
})
Array Operators
-- Value in array
local specific = players:Find({
class = { ["$in"] = { "Warrior", "Mage", "Rogue" } }
})
-- Value not in array
local nonCombat = players:Find({
class = { ["$nin"] = { "Warrior", "Mage", "Rogue" } }
})
Logical Operators
-- AND (implicit with multiple fields)
local vipWarriors = players:Find({
class = "Warrior",
vip = true
})
-- OR
local highRank = players:Find({
["$or"] = {
{ level = { ["$gte"] = 50 } },
{ vip = true }
}
})
-- AND with OR
local complexQuery = players:Find({
class = "Warrior",
["$or"] = {
{ level = { ["$gte"] = 20 } },
{ experience = { ["$gte"] = 10000 } }
}
})
Existence Check
-- Field exists
local hasInventory = players:Find({
inventory = { ["$exists"] = true }
})
-- Field doesn't exist
local noInventory = players:Find({
inventory = { ["$exists"] = false }
})
Async Query Operations
FindAsync
collection:FindAsync(filter, limit, callback)
limit is required and must be passed between the filter and the callback. If you skip it, your callback will receive no documents and will appear to not fire. Pass the maximum number of documents you want back (e.g. 100).collection:FindAsync({ level = { ["$gte"] = 10 } }, 100, function(err, results)
if err then
print("Query error:", err)
return
end
print("Found", #results, "players")
for _, player in ipairs(results) do
print(" " .. player.username)
end
end)
FindOneAsync
collection:FindOneAsync({ steamid = "STEAM_0:1:12345" }, function(err, player)
if err then
print("Query error:", err)
return
end
if player then
print("Found:", player.username)
else
print("Player not found")
end
end)
CountAsync
collection:CountAsync({ active = true }, function(err, count)
if err then
print("Count error:", err)
return
end
print("Active players:", count)
end)
Practical Examples
Player Lookup
function GetPlayer(steamid)
local players = db:Collection("players")
return players:FindOne({ steamid = steamid })
end
function GetPlayerAsync(steamid, callback)
local players = db:Collection("players")
players:FindOneAsync({ steamid = steamid }, function(err, player)
if err then
callback(nil, err)
else
callback(player, nil)
end
end)
end
Leaderboard
function GetTopPlayers(limit)
local players = db:Collection("players")
-- Note: For sorted results, use Aggregate
local results = players:Find(
{ banned = { ["$ne"] = true } },
limit or 10
)
return results
end
Search Players
function SearchPlayers(criteria)
local players = db:Collection("players")
local filter = {}
if criteria.minLevel then
filter.level = filter.level or {}
filter.level["$gte"] = criteria.minLevel
end
if criteria.maxLevel then
filter.level = filter.level or {}
filter.level["$lte"] = criteria.maxLevel
end
if criteria.class then
filter.class = criteria.class
end
if criteria.vipOnly then
filter.vip = true
end
return players:Find(filter, criteria.limit or 100)
end
-- Usage
local results = SearchPlayers({
minLevel = 10,
class = "Warrior",
limit = 50
})
Online Player Check
function GetOnlinePlayers(steamids)
local players = db:Collection("players")
return players:Find({
steamid = { ["$in"] = steamids }
})
end
-- Usage
local online = GetOnlinePlayers({
"STEAM_0:1:11111",
"STEAM_0:1:22222",
"STEAM_0:1:33333"
})
Best Practices
- Use FindOne when expecting single result: More efficient than Find
- Add limits to Find: Prevent memory issues with large collections
- Use indexes: Create indexes on frequently queried fields
- Use async for gameplay: Avoid blocking during game logic
- Check for nil: Always handle not-found cases
Next Steps
- Update Operations - Modify documents
- Query Operators - Advanced filtering
- Async Operations - Non-blocking queries