Skip to main content
MongoDB is a perfect choice for this kind of system due to its flexible schema. The Collection-per-Type pattern you’ve suggested is a great way to maintain clarity and optimize indexes for specific asset types. Here is a high-level design using this pattern, with detailed document structures for a generalAssets collection and a specific itAssets collection.

1. Design Principle: Collection-per-Type

  • Base Fields in Every Collection: We will define a set of common fields (the “base schema”) that will exist in every asset collection. This consistency is enforced at the application layer (e.g., through a base class or a schema validation library like Mongoose or Zod).
  • Specific Fields per Collection: Each collection will extend the base schema with fields that are unique to that asset type.
  • No Inheritance at the DB Level: Unlike the relational model, there’s no direct inheritance or joining. Each document in a collection is self-contained. To find “all assets assigned to a user,” you would need to query each relevant asset collection (generalAssets, itAssets, etc.) and merge the results in your application.

2. Base Field Set Structure

This is the common structure that will be part of every asset document, regardless of its collection.
// --- BASE ASSET FIELDS ---
{
  "_id": ObjectId("..."), // Automatically generated by MongoDB
  "assetTag": "string",     // Unique, human-readable identifier (e.g., "GEN-MTR-0012")
  "name": "string",         // Descriptive name (e.g., "Forklift 3B", "Conference Room Projector")
  "status": "string",       // e.g., 'In Use', 'In Storage', 'Under Maintenance', 'Decommissioned'

  "location": {             // Embedded object for location details
    "building": "string",
    "floor": "string",
    "room": "string",
    "description": "string" // e.g., "Northwest corner of Warehouse B"
  },

  "manufacturer": "string",   // e.g., "Toyota", "Caterpillar", "Epson"

  "purchaseInfo": {         // Grouped purchasing information
    "purchaseDate": "Date",
    "vendor": "string",
    "cost": "Number",
    "warrantyExpiryDate": "Date"
  },

  "assignment": {           // Grouped assignment information
    "assignedToUserId": "ObjectId", // Reference to a 'users' collection
    "assignedToName": "string",   // Denormalized for quick display
    "assignmentDate": "Date"
  },

  "notes": "string",          // General purpose notes field

  "audit": {                // Timestamps
    "createdAt": "Date",
    "updatedAt": "Date"
  }
}

3. Document Structure for generalAssets Collection

This collection will store assets like vehicles and machinery. We’ll add a category field to differentiate them within this collection and a flexible specifications object.

Example Document: A Vehicle in generalAssets

// Collection: generalAssets
{
  // --- BASE ASSET FIELDS (Copied from above) ---
  "_id": ObjectId("638d1c7a5d1e4e3f8b0e7a12"),
  "assetTag": "VEH-TRK-007",
  "name": "Field Operations Pickup Truck",
  "status": "In Use",
  "location": {
    "building": "Main Garage",
    "floor": "1",
    "room": "Bay 3",
    "description": "Parking spot G3"
  },
  "manufacturer": "Ford",
  "purchaseInfo": {
    "purchaseDate": "2022-08-15T00:00:00.000Z",
    "vendor": "City Ford Dealership",
    "cost": 45000.50,
    "warrantyExpiryDate": "2025-08-14T00:00:00.000Z"
  },
  "assignment": {
    "assignedToUserId": ObjectId("638d1c0a5d1e4e3f8b0e7a01"),
    "assignedToName": "John Doe",
    "assignmentDate": "2022-09-01T00:00:00.000Z"
  },
  "notes": "Equipped with a toolbox and ladder rack.",
  "audit": {
    "createdAt": "2022-08-15T14:30:00.000Z",
    "updatedAt": "2023-11-20T10:00:00.000Z"
  },

  // --- GENERAL ASSET SPECIFIC FIELDS ---
  "category": "VEHICLE", // Discriminator within this collection

  "specifications": {
    // Fields specific to a VEHICLE
    "vin": "1FTRExAMPLEvIN7GA12345",
    "licensePlate": "5XYZ123",
    "model": "F-150",
    "year": 2022,
    "mileage": 25480,
    "fuelType": "Gasoline",
    "lastServiceDate": "2023-10-15T00:00:00.000Z"
  }
}

Example Document: Machinery in generalAssets

Notice how the specifications object structure changes based on the category.
// Collection: generalAssets
{
  // ... Base Asset Fields ...
  "assetTag": "MAC-FL-003",
  "name": "Warehouse Forklift 3B",
  "category": "MACHINERY",
  "specifications": {
    // Fields specific to MACHINERY
    "serialNumber": "CAT-SN-987654321",
    "modelNumber": "DP25N",
    "hoursOfOperation": 4120,
    "maxLoadKg": 2500,
    "lastMaintenanceDate": "2023-09-30T00:00:00.000Z"
  }
}

4. Document Structure for itAssets Collection

This collection is specifically for IT equipment and has a different set of specific fields tailored to technology.

Example Document: A Laptop in itAssets

// Collection: itAssets
{
  // --- BASE ASSET FIELDS (Copied from above) ---
  "_id": ObjectId("638d1d8f5d1e4e3f8b0e7b45"),
  "assetTag": "IT-LPT-01124",
  "name": "Dell Latitude 7420",
  "status": "In Use",
  "location": {
    "building": "Building A",
    "floor": "4",
    "room": "401",
    "description": "Desk 4-15"
  },
  "manufacturer": "Dell",
  "purchaseInfo": {
    "purchaseDate": "2023-01-20T00:00:00.000Z",
    "vendor": "Dell Corporate Sales",
    "cost": 1850.50,
    "warrantyExpiryDate": "2026-01-19T00:00:00.000Z"
  },
  "assignment": {
    "assignedToUserId": ObjectId("638d1c0a5d1e4e3f8b0e7a05"),
    "assignedToName": "Jane Smith",
    "assignmentDate": "2023-01-25T00:00:00.000Z"
  },
  "notes": "Docking station and two monitors included.",
  "audit": {
    "createdAt": "2023-01-20T11:00:00.000Z",
    "updatedAt": "2023-01-25T09:15:00.000Z"
  },

  // --- IT ASSET SPECIFIC FIELDS ---
  "network": {
    "hostname": "LPT-JSMITH-PROD",
    "macAddress": "9C:B6:D0:FF:1A:3E",
    "ipAddress": "192.168.1.152"
  },

  "hardware": {
    "cpu": "Intel Core i7-1185G7",
    "ram": {
      "sizeGb": 16,
      "type": "DDR4"
    },
    "storage": [ // An array to support multiple drives
      {
        "type": "SSD",
        "sizeGb": 512
      }
    ]
  },

  "software": {
    "operatingSystem": {
      "name": "Windows 11 Pro",
      "version": "22H2"
    }
  }
}

Summary of Benefits with this MongoDB Design

  • Schema Flexibility: You can easily add a new field to itAssets (e.g., isEncrypted) without affecting any other collection. The specifications object in generalAssets can hold vastly different structures for a vehicle vs. a generator.
  • Query Performance: Queries within a single collection are highly optimized. Finding all laptops with 16GB of RAM (db.itAssets.find({"hardware.ram.sizeGb": 16})) is very fast because the query only scans the relevant collection.
  • Clarity and Maintainability: As you requested, separating asset types into their own collections makes the system’s structure intuitive. A developer working on IT asset features can focus entirely on the itAssets collection and its schema.
  • Scalability: Adding a new asset class, like Furniture, is as simple as creating a new furnitureAssets collection and defining its document structure in your application code.