Basic Aggregates

Generic Description

Use the basic aggregate surface to compute grouped or global summaries such as row counts, sums, averages, minima, and maxima. Documenting it separately matters because aggregate placement changes row grain, grouping behavior, and whether state/merge forms are valid.

Simple example:

MATCH (u:User)-[:HAS_APP_SESSION]->(s:AppSession)
RETURN u.profile.location.country AS country,
       count(s) AS sessions,
       sum(s.duration_seconds) AS total_duration,
       avg(s.duration_seconds) AS avg_duration,
       min(s.duration_seconds) AS min_duration,
       max(s.duration_seconds) AS max_duration
ORDER BY country

Consumer-Level Explanation

These are the foundation aggregates you use when the goal is to turn a stream of matched rows into metrics that are easy to read, chart, or feed into later analytical steps.

In Nexyron they matter beyond simple reporting because they are the common summary layer that sits between:

If your query is “how many,” “how much,” “what is the average,” or “what is the range,” this is the starting family.

More Detailed Explanation

The implemented core set is:

The current alias layer also includes:

Those functions run through the normal Cypher aggregate planning path and currently feed both:

They are also the base layer for the exact incremental materialized aggregate-view subset. That subset stores mathematically sufficient per-group state instead of re-running the whole view query after each safe write.

This matters architecturally because Nexyron is not trying to bolt on a separate analytics DSL. The same Cypher query can:

  1. match graph structure
  2. read nested map/list payloads
  3. apply temporal filters
  4. aggregate grouped metrics

without switching surfaces.

Advanced Example

MATCH (u:User)-[e:INTERACTED_WITH]->(p:Post)
TIME e.ts BETWEEN datetime('2026-03-01T00:00:00Z') AND datetime('2026-03-31T23:59:59Z')
WITH u,
     p,
     date_trunc('day', e.ts) AS day_bucket,
     properties(p.metadata) AS post_meta
RETURN u.profile.location.country AS country,
       day_bucket,
       count(*) AS interactions,
       sum(p.engagement_rate) AS total_engagement,
       avg(p.engagement_rate) AS avg_engagement,
       min(size(keys(post_meta))) AS min_metadata_fields,
       max(size(keys(post_meta))) AS max_metadata_fields
ORDER BY country, day_bucket

Real Use Cases

Real Limitations And Tradeoffs