Skip to content

Relational Classifications: Core Concepts

Relational classifications evaluate a row based on its relationships with other rows. Instead of looking only at values in the current table, they follow defined relationships to connected data and apply conditions to the results. Each relational classification resolves to true or false for every row in the table where it is defined.

Relational classifications are fully declarative. Once configured, Minyu evaluates them automatically and keeps them up to date whenever related data changes or time affects the outcome.

What a Relations Path Is

A relations path defines how the system moves from the starting row to other related rows. It determines where the evaluation begins, which relations are followed, and which rows form the final result set.

A relations path has three components:

  1. Start The row being evaluated in the table where the classification is defined.

  2. Traversal One or more relationships (1:1, 1:n, n:1, n:n) followed across the data model.

  3. Target Rows The resulting rows at the end of the path. These are the rows counted and evaluated by the classification.

Minyu always treats the result as a distinct set of rows.

flowchart LR
    E["Employee"]
    D["Department"]
    B["Building"]
    I["Safety Inspection"]

    E -->|"works in"| D
    D -->|"located in"| B
    B -->|"inspections"| I

Figure: Example of a relational classification aimed at finding employees that works in building where there has been a certain number of inspections.

#include <stdio.h>

int main(void) {
  printf("Hello world!\n");
  return 0;
}
#include <iostream>

int main(void) {
  std::cout << "Hello world!" << std::endl;
  return 0;
}
Person gender is set
flowchart TB
subgraph Person
   p1["[Steve]"]
end

subgraph Gender
   p2["[Male]"]
end

p1 --> Gender
p2 --> |"Evaluation"|eval{"count distinct = 1"} -->|Outcome| A@{ shape: dbl-circ, label: "True" }
Male person who has one female friend
flowchart TB

   subgraph Person
      barry["Barry"] --> 
      is_male{"Is Male"} --- 
      y1@{ shape: text, label: "Yes [Barry]" }
   end

   subgraph Friends
      friends["[Ann, Steve, David]"]
      friends --> is_female{Is Female} --- y2@{ shape: text, label: "Yes [Ann]" }
   end

   y1 --> Friends

   y2 -->|"Evaluation"| eval{"count distinct = 1"} -->|Outcome| A@{ shape: dbl-circ, label: "True" }

Person who has friends that are friends
flowchart TB

   subgraph "Persons (Collection)"
      barry["Barry"] 
   end

   subgraph "Persons (Collection)"
      friends["[Ann, Steve, David]"]
   end

   subgraph "Persons (Collection)"
      friends2["[Charlie, David, Sam, Barry]"] -->|"Charlie
      David
      Sam
      Barry"| intersection{"Intersection-
      filter"}
      friends -->|"Ann
      Steve
      David"| intersection
   end         

   barry -->|"Friends (Relation)"| friends

   friends -->|"Friends (Relation)"| friends2

   intersection ---david@{ shape: text, label: "David" }

   david -->|"Evaluation"| eval{"count distinct > 0"} -->|Outcome| A@{ shape: dbl-circ, label: "True" }

How a Relational Classification Is Evaluated

A relational classification combines a path with an expectation:

  1. Follow the defined relations path from the start row.
  2. Collect all distinct target rows.
  3. Filter the rows if needed
  4. Count them.
  5. Compare the count to the expected condition (e.g., > 0, = 0, > 5).

If the comparison is true, the classification resolves to true. Otherwise, it resolves to false.

The classification is re-evaluated automatically whenever dependent rows change or when time affects any part of the condition (for example, when date-based filters are used later on).

Examples

These simple examples illustrate typical relational paths without filters:

Example: A Customer Has an Order

  • Start at Customer
  • Follow relation to Orders
  • Condition: count > 0
flowchart TB
subgraph Person
   p1["[Steve]"]
end

subgraph Gender
   p2["[Male]"]
end

p1 --> Gender
p2 --> |"Evaluation"|eval{"count distinct = 1"} -->|Outcome| A@{ shape: dbl-circ, label: "True" }

Example: A Product Has Categories

  • Start at Product
  • Follow relation to ProductCategory
  • Condition: count > 0

Example: A Person Has a Salutation

  • Start at Person
  • Follow to Salutation
  • Condition: count = 1

These are the simplest forms of relational classifications. Filtering is introduced in later articles.

Performance Limits

To ensure predictable performance, Minyu enforces a limit on how many rows a relational classification may evaluate. After all filters on the path have been applied, no step may produce more than 100 resulting rows.

This is checked periodically. If a relational classification expands to more than 100 rows after filtering, the system automatically disables it.

This prevents runaway path expansions and ensures classifications remain fast and stable during evaluation.

Relational classification depth limit

Relational classifications are limited to a maximum of 15 relation steps.
Deeper relation chains are not allowed, as they introduce excessive processing cost and unpredictable evaluation behavior.