Skip to main content

Data Model Concepts

This document explains the fundamental data modeling concepts in OctoMesh, including Construction Kits, Runtime Entities, and Stream Data.

Overview

OctoMesh uses a two-layer data model approach:

  1. Construction Kit (CK): Schema definitions that describe the structure of your data
  2. Runtime (RT): Actual data instances based on Construction Kit definitions

Construction Kit (CK)

What is a Construction Kit?

A Construction Kit is a type system that defines the structure and relationships of your data domain. Think of it as a schema or blueprint for your data.

CK Libraries

Construction Kits are organized into libraries:

System (base library)
├── Industry.Energy
├── Industry.Manufacturing
├── Industry.Logistics
└── Custom.MyCompany

Every library depends on the System library, which provides fundamental types and definitions.

CK Types

Types are the primary building blocks that define entities in your domain.

Example: Energy Meter Type

Type: EnergyMeter
Namespace: Industry.Energy
BaseType: System.Asset
Attributes:
- serialNumber: string
- manufacturer: string
- installationDate: dateTime
- maxCapacity: decimal
Associations:
- location: Industry.Common.Location (1:1)
- readings: Industry.Energy.MeterReading (1:N)

Type Inheritance

Types can inherit from other types, gaining all attributes and associations:

Attributes

Attributes define the properties of a type.

Attribute TypeDescriptionExample
stringText valueName, description
intInteger numberCount, quantity
decimalDecimal numberPrice, measurement
booleanTrue/falseIsActive, isEnabled
dateTimeDate and timeCreatedAt, modifiedAt
binaryBinary dataFile content, images
geoGeospatial dataLocation coordinates

Attribute Metadata:

  • isRequired: Whether the attribute must have a value
  • defaultValue: Default value if not specified
  • validationRules: Constraints on allowed values

Records

Records are complex attributes that contain multiple fields. They are useful for grouping related data.

Example: Address Record

Record: Address
Fields:
- street: string
- city: string
- postalCode: string
- country: string

Usage in a Type:

Type: Customer
Attributes:
- name: string
- billingAddress: Address (Record)
- shippingAddress: Address (Record)

Associations

Associations define relationships between types.

Association Multiplicities:

MultiplicityDescription
1:1One-to-one relationship
1:NOne-to-many relationship
N:MMany-to-many relationship

Association Roles: Each association has two roles defining the relationship from each side:

Enums

Enums define controlled vocabularies for semantic values:

Enum: MeterStatus
Values:
- Active
- Inactive
- Maintenance
- Decommissioned

Usage:

Type: EnergyMeter
Attributes:
- status: MeterStatus (Enum)

Runtime Entities (RT)

What is a Runtime Entity?

A Runtime Entity is an instance of a Construction Kit Type. It represents actual data stored in the system.

RT Structure

{
"rtId": "550e8400-e29b-41d4-a716-446655440000",
"ckTypeId": "Industry.Energy/EnergyMeter",
"wellKnownName": "main-building-meter",
"attributes": {
"name": "Main Building Meter",
"serialNumber": "EM-2024-001",
"manufacturer": "Siemens",
"installationDate": "2024-01-15T00:00:00Z",
"maxCapacity": 1000.0,
"status": "Active"
},
"associations": {
"location": {
"items": ["location-rtid-123"]
},
"readings": {
"items": ["reading-rtid-1", "reading-rtid-2"]
}
}
}

Key Properties

PropertyDescription
rtIdUnique identifier (GUID)
ckTypeIdReference to the Construction Kit Type
wellKnownNameHuman-readable unique name (optional)
attributesAttribute values
associationsReferences to related entities

Working with RT Entities

Creating an Entity (via GraphQL):

mutation {
runtime {
createRtIndustryEnergyEnergyMeter(
entity: {
attributes: {
name: "New Meter"
serialNumber: "EM-2024-002"
status: Active
}
}
) {
rtId
}
}
}

Querying Entities:

query {
runtime {
rtIndustryEnergyEnergyMeter(
first: 10
filter: { status: { eq: "Active" } }
) {
items {
rtId
name
serialNumber
location {
items {
name
address
}
}
}
}
}
}

Updating an Entity:

mutation {
runtime {
updateRtIndustryEnergyEnergyMeter(
rtId: "550e8400-e29b-41d4-a716-446655440000"
entity: {
attributes: {
status: Maintenance
}
}
) {
rtId
}
}
}

Stream Data (Time Series)

What is Stream Data?

Stream Data represents continuous, time-sensitive data such as:

  • Sensor readings
  • Event logs
  • Metrics and measurements
  • Financial data

Stream Data Storage

Stream data is stored in CrateDB for optimized:

  • High-throughput ingestion
  • Time-based queries
  • Real-time analytics

Stream Data Structure

{
"rtId": "550e8400-e29b-41d4-a716-446655440000",
"ckTypeId": "Industry.Energy/EnergyMeter",
"timeStamp": "2024-01-15T10:30:00Z",
"voltage": 230.5,
"current": 15.2,
"power": 3503.6,
"frequency": 50.0
}

Querying Stream Data

query {
streamData {
tsIndustryEnergyEnergyMeter(
first: 100
filter: {
rtId: { eq: "550e8400-e29b-41d4-a716-446655440000" }
timeStamp: {
gte: "2024-01-15T00:00:00Z"
lte: "2024-01-15T23:59:59Z"
}
}
orderBy: { timeStamp: DESC }
) {
items {
timeStamp
voltage
current
power
}
pageInfo {
hasNextPage
endCursor
}
}
}
}

Stream Data vs. Runtime Data

AspectRuntime DataStream Data
StorageMongoDBCrateDB
PurposeMaster data, entitiesTime-series, events
UpdatesMutableAppend-only
QueriesEntity-basedTime-based
VolumeModerateHigh

Data Flow

Best Practices

Designing Construction Kits

  1. Start with the System library: Use existing base types where possible
  2. Use inheritance wisely: Create hierarchies for shared behavior
  3. Keep types focused: Each type should represent a single concept
  4. Use Records for embedded data: Group related attributes together
  5. Define meaningful associations: Model real-world relationships

Working with Runtime Data

  1. Use wellKnownName for lookups: More readable than GUIDs
  2. Filter early: Use query filters to reduce data transfer
  3. Paginate large results: Always use first and after parameters
  4. Include only needed fields: Optimize GraphQL queries

Managing Stream Data

  1. Design for time-based queries: Include proper time fields
  2. Consider data retention: Plan for data lifecycle management
  3. Batch writes: Group multiple data points for efficiency
  4. Use appropriate granularity: Don't store more detail than needed

Next Steps