MATIH Platform is in active MVP development. Documentation reflects current implementation status.
14. Context Graph & Ontology
Ontology Service

Ontology Service

The Ontology Service is a standalone Python/FastAPI microservice (port 8101) that manages entity relationships, semantic models, and domain ontologies for the MATIH platform. It provides a GraphQL API for querying entity types and relationships, REST APIs for CRUD operations, and integrates with Dgraph for graph-native storage.


Architecture

Ontology Service (Port 8101)
    |
    +-- API Layer
    |   +-- REST Routes (/api/v1/ontology/*)
    |   +-- GraphQL Endpoint (/graphql)
    |
    +-- Models Layer
    |   +-- ObjectType (entity definitions)
    |   +-- Enums (classification types)
    |   +-- Semantic Models (semantic relationships)
    |
    +-- Service Layer
    |   +-- OntologyService (core business logic)
    |   +-- SchemaMapping (data catalog mapping)
    |
    +-- Storage Layer
    |   +-- Dgraph Repository (graph storage)
    |   +-- Templates (ontology templates)
    |
    +-- Configuration
        +-- config.py (service settings)

Source Organization

The Ontology Service is organized under data-plane/ontology-service/src/:

src/
  main.py                 # FastAPI entry point
  config.py               # Service configuration
  api/
    routes/               # REST API route handlers
    graphql/              # GraphQL schema and resolvers
  models/
    object_type.py        # Entity type definitions
    enums.py              # Enumeration types
    semantic/             # Semantic model definitions
  storage/                # Storage backends
  schema_mapping/         # Schema-to-ontology mapping
  templates/              # Ontology templates

Data Model

Entity Types

The Ontology Service manages entity types that define the domain vocabulary:

class ObjectType:
    """An entity type in the ontology."""
    urn: str                    # Unique resource name
    name: str                   # Human-readable name
    description: str            # Entity description
    namespace: str              # Ontology namespace
    properties: list[Property]  # Entity properties
    relationships: list[Relationship]  # Connections to other types
    parent_type: str | None     # Inheritance hierarchy
    tags: list[str]             # Classification tags
    tenant_id: str              # Owning tenant

Properties

class Property:
    """A property of an entity type."""
    name: str
    data_type: str              # string, int, float, date, boolean
    description: str
    required: bool = False
    indexed: bool = False
    searchable: bool = False
    default_value: Any | None = None

Relationships

class Relationship:
    """A relationship between entity types."""
    name: str
    source_type: str
    target_type: str
    cardinality: str            # one_to_one, one_to_many, many_to_many
    description: str
    inverse_name: str | None = None
    properties: list[Property] = []

GraphQL API

The Ontology Service exposes a GraphQL endpoint for flexible entity queries:

Schema

type ObjectType {
    urn: String!
    name: String!
    description: String
    namespace: String!
    properties: [Property!]!
    relationships: [Relationship!]!
    parentType: ObjectType
    childTypes: [ObjectType!]!
    tags: [String!]!
}
 
type Property {
    name: String!
    dataType: String!
    description: String
    required: Boolean!
    indexed: Boolean!
}
 
type Relationship {
    name: String!
    sourceType: ObjectType!
    targetType: ObjectType!
    cardinality: String!
    description: String
    inverseName: String
}
 
type Query {
    objectType(urn: String!): ObjectType
    objectTypes(
        namespace: String
        tags: [String!]
        limit: Int = 50
    ): [ObjectType!]!
    searchEntities(
        query: String!
        limit: Int = 20
    ): [ObjectType!]!
    relationships(
        sourceUrn: String!
        depth: Int = 1
    ): [Relationship!]!
}
 
type Mutation {
    createObjectType(input: CreateObjectTypeInput!): ObjectType!
    updateObjectType(urn: String!, input: UpdateObjectTypeInput!): ObjectType!
    deleteObjectType(urn: String!): Boolean!
    addRelationship(input: AddRelationshipInput!): Relationship!
    removeRelationship(
        sourceUrn: String!
        targetUrn: String!
        name: String!
    ): Boolean!
}

Example Query

query {
    objectType(urn: "urn:matih:ontology:acme:customer") {
        name
        description
        properties {
            name
            dataType
            required
        }
        relationships {
            name
            targetType {
                name
                urn
            }
            cardinality
        }
    }
}

REST API

Entity Type Operations

POST   /api/v1/ontology/types              # Create entity type
GET    /api/v1/ontology/types              # List entity types
GET    /api/v1/ontology/types/{urn}         # Get entity type
PUT    /api/v1/ontology/types/{urn}         # Update entity type
DELETE /api/v1/ontology/types/{urn}         # Delete entity type

Relationship Operations

POST   /api/v1/ontology/relationships                    # Add relationship
GET    /api/v1/ontology/relationships?source_urn=...     # List relationships
DELETE /api/v1/ontology/relationships/{id}                # Remove relationship

Search Operations

GET    /api/v1/ontology/search?query=customer&limit=10   # Semantic search
GET    /api/v1/ontology/graph?urn=...&depth=2            # Graph traversal

Schema Mapping

The schema mapping module connects ontology entities to physical data catalog tables:

class SchemaMapper:
    """Maps ontology entities to data catalog tables."""
 
    async def map_entity_to_table(
        self,
        entity_urn: str,
        table_fqn: str,
        column_mappings: dict[str, str],
    ) -> SchemaMapping:
        """Create a mapping between an ontology entity and a table."""
        return SchemaMapping(
            entity_urn=entity_urn,
            table_fqn=table_fqn,
            column_mappings=column_mappings,
        )
 
    async def resolve_entity(
        self,
        entity_urn: str,
    ) -> TableResolution:
        """Resolve an ontology entity to its physical table(s)."""
        mappings = await self._get_mappings(entity_urn)
        return TableResolution(
            entity_urn=entity_urn,
            tables=[m.table_fqn for m in mappings],
            columns={
                m.table_fqn: m.column_mappings for m in mappings
            },
        )

Mapping Example

{
    "entity_urn": "urn:matih:ontology:acme:customer",
    "table_fqn": "analytics.crm.customers",
    "column_mappings": {
        "customer_id": "id",
        "full_name": "name",
        "email_address": "email",
        "signup_date": "created_at",
        "lifetime_value": "ltv"
    }
}

Ontology Templates

Pre-built ontology templates for common business domains:

TemplateDomainEntity Types
E-CommerceRetailCustomer, Product, Order, Category, Review
SaaSSoftwareUser, Subscription, Feature, Usage, Invoice
HealthcareMedicalPatient, Provider, Appointment, Diagnosis, Prescription
FinanceBankingAccount, Transaction, Customer, Instrument, Portfolio
ManufacturingIndustrialProduct, Component, Supplier, WorkOrder, Quality

Integration with AI Service

The AI Service queries the Ontology Service to enrich agent context:

# Within AI Service
class OntologyClient:
    """Client for Ontology Service integration."""
 
    async def resolve_entities(
        self,
        query: str,
        tenant_id: str,
    ) -> list[dict[str, Any]]:
        """Resolve entities mentioned in a query."""
        response = await self._http.get(
            f"{self._base_url}/api/v1/ontology/search",
            params={"query": query, "tenant_id": tenant_id},
        )
        return response.json()["results"]
 
    async def get_relationships(
        self,
        entity_urn: str,
        depth: int = 1,
    ) -> list[dict[str, Any]]:
        """Get relationships for an entity."""
        response = await self._http.get(
            f"{self._base_url}/api/v1/ontology/graph",
            params={"urn": entity_urn, "depth": depth},
        )
        return response.json()["relationships"]

Dgraph Storage

The Ontology Service uses Dgraph for graph-native entity storage:

AdvantageDescription
Native graph queriesTraversals without JOIN operations
Schema flexibilityAdd properties and relationships dynamically
Full-text searchDgraph's built-in full-text indexing
Multi-tenancyTenant-isolated queries via predicates
GraphQL nativeDgraph supports GraphQL mutations/queries natively