CRUD Operations

Insert Operations

Create new documents in MongoDB collections

Insert Operations

Learn how to insert documents into MongoDB collections.

InsertOne

Insert a single document into a collection.

Syntax

local insertedId = collection:InsertOne(document)

Parameters

  • document (table): The document to insert

Returns

  • string: The inserted document's ObjectId
  • nil: On failure

Example

local players = db:Collection("players")

local id = players:InsertOne({
    steamid = "STEAM_0:1:12345678",
    username = "NewPlayer",
    level = 1,
    credits = 1000,
    joined_at = os.time(),
    inventory = {},
    stats = {
        kills = 0,
        deaths = 0,
        playtime = 0
    }
})

if id then
    print("Inserted player with ID:", id)
else
    print("Insert failed!")
end

Document Structure

Documents are Lua tables that convert to BSON:

-- Simple document
{
    name = "Test",
    value = 42
}

-- Nested document
{
    player = {
        name = "Test",
        level = 10
    },
    items = { "sword", "shield", "potion" }
}

-- With various types
{
    string_field = "hello",
    number_field = 123,
    float_field = 3.14,
    boolean_field = true,
    array_field = { 1, 2, 3 },
    nested_field = { key = "value" },
    timestamp = os.time()
}

InsertMany

Insert multiple documents in a single operation.

Syntax

local insertedIds = collection:InsertMany(documents)

Parameters

  • documents (table): Array of documents to insert

Returns

  • table: Array of inserted ObjectIds
  • nil: On failure

Example

local players = db:Collection("players")

local ids = players:InsertMany({
    {
        steamid = "STEAM_0:1:11111111",
        username = "Player1",
        level = 5,
        credits = 5000
    },
    {
        steamid = "STEAM_0:1:22222222",
        username = "Player2",
        level = 10,
        credits = 10000
    },
    {
        steamid = "STEAM_0:1:33333333",
        username = "Player3",
        level = 15,
        credits = 15000
    }
})

if ids then
    print("Inserted", #ids, "players:")
    for i, id in ipairs(ids) do
        print("  " .. i .. ": " .. id)
    end
else
    print("Batch insert failed!")
end

Performance Benefits

InsertMany is more efficient than multiple InsertOne calls:

-- Inefficient (multiple round trips)
for i = 1, 100 do
    collection:InsertOne({ index = i })
end

-- Efficient (single round trip)
local docs = {}
for i = 1, 100 do
    table.insert(docs, { index = i })
end
collection:InsertMany(docs)

Async Insert Operations

For non-blocking inserts, use the async variants.

InsertOneAsync

collection:InsertOneAsync(document, function(err, result)
    if err then
        print("Error:", err)
    else
        print("Inserted ID:", result)
    end
end)

InsertManyAsync

collection:InsertManyAsync(documents, function(err, results)
    if err then
        print("Error:", err)
    else
        print("Inserted", #results, "documents")
        for i, id in ipairs(results) do
            print("  " .. id)
        end
    end
end)

Practical Examples

Player Registration

function RegisterPlayer(steamid, username)
    local players = db:Collection("players")

    -- Check if player exists
    local existing = players:FindOne({ steamid = steamid })
    if existing then
        return false, "Player already registered"
    end

    -- Insert new player
    local id = players:InsertOne({
        steamid = steamid,
        username = username,
        level = 1,
        experience = 0,
        credits = 1000,
        created_at = os.time(),
        last_login = os.time(),
        settings = {
            notifications = true,
            language = "en"
        }
    })

    if id then
        return true, id
    else
        return false, "Database error"
    end
end

-- Usage
local success, result = RegisterPlayer("STEAM_0:1:12345", "NewPlayer")
if success then
    print("Registered with ID:", result)
else
    print("Failed:", result)
end

Batch Item Creation

function CreateItems(items)
    local itemCollection = db:Collection("items")

    local docs = {}
    for _, item in ipairs(items) do
        table.insert(docs, {
            item_id = item.id,
            name = item.name,
            type = item.type,
            rarity = item.rarity or "common",
            stats = item.stats or {},
            created_at = os.time()
        })
    end

    local ids = itemCollection:InsertMany(docs)
    return ids and #ids or 0
end

-- Usage
local count = CreateItems({
    { id = "sword_1", name = "Iron Sword", type = "weapon" },
    { id = "shield_1", name = "Wooden Shield", type = "armor" },
    { id = "potion_1", name = "Health Potion", type = "consumable" }
})
print("Created", count, "items")

Logging System

function LogEvent(category, message, data)
    local logs = db:Collection("logs")

    logs:InsertOneAsync({
        category = category,
        message = message,
        data = data or {},
        timestamp = os.time(),
        server_id = GetHostName()
    }, function(err, id)
        if err then
            print("Log failed:", err)
        end
        -- Fire and forget - don't block game
    end)
end

-- Usage (non-blocking)
LogEvent("player", "Player joined", { steamid = "STEAM_0:1:12345" })
LogEvent("economy", "Purchase made", { item = "weapon", cost = 500 })

Error Handling

local function safeInsert(collection, document)
    local success, result = pcall(function()
        return collection:InsertOne(document)
    end)

    if not success then
        print("Insert error:", result)
        return nil
    end

    return result
end

-- Usage
local id = safeInsert(players, { name = "Test" })
if id then
    print("Success:", id)
end

Best Practices

  1. Use InsertMany for bulk operations: More efficient than multiple InsertOne calls
  2. Include timestamps: Add created_at fields for tracking
  3. Use async for game logic: Prevents blocking during gameplay
  4. Validate before insert: Check data integrity before writing
  5. Handle errors: Always check return values

Next Steps