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:
- Construction Kit (CK): Schema definitions that describe the structure of your data
- 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 Type | Description | Example |
|---|---|---|
string | Text value | Name, description |
int | Integer number | Count, quantity |
decimal | Decimal number | Price, measurement |
boolean | True/false | IsActive, isEnabled |
dateTime | Date and time | CreatedAt, modifiedAt |
binary | Binary data | File content, images |
geo | Geospatial data | Location coordinates |
Attribute Metadata:
isRequired: Whether the attribute must have a valuedefaultValue: Default value if not specifiedvalidationRules: 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:
| Multiplicity | Description |
|---|---|
1:1 | One-to-one relationship |
1:N | One-to-many relationship |
N:M | Many-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
| Property | Description |
|---|---|
rtId | Unique identifier (GUID) |
ckTypeId | Reference to the Construction Kit Type |
wellKnownName | Human-readable unique name (optional) |
attributes | Attribute values |
associations | References 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
| Aspect | Runtime Data | Stream Data |
|---|---|---|
| Storage | MongoDB | CrateDB |
| Purpose | Master data, entities | Time-series, events |
| Updates | Mutable | Append-only |
| Queries | Entity-based | Time-based |
| Volume | Moderate | High |
Data Flow
Best Practices
Designing Construction Kits
- Start with the System library: Use existing base types where possible
- Use inheritance wisely: Create hierarchies for shared behavior
- Keep types focused: Each type should represent a single concept
- Use Records for embedded data: Group related attributes together
- Define meaningful associations: Model real-world relationships
Working with Runtime Data
- Use wellKnownName for lookups: More readable than GUIDs
- Filter early: Use query filters to reduce data transfer
- Paginate large results: Always use
firstandafterparameters - Include only needed fields: Optimize GraphQL queries
Managing Stream Data
- Design for time-based queries: Include proper time fields
- Consider data retention: Plan for data lifecycle management
- Batch writes: Group multiple data points for efficiency
- Use appropriate granularity: Don't store more detail than needed
Next Steps
- Construction Kit Engine: Learn how to compile and work with Construction Kits
- SDK Overview: Explore the SDK libraries
- API Integration: Connect to OctoMesh APIs