Skip to content

Latest commit

 

History

History
151 lines (110 loc) · 7.19 KB

File metadata and controls

151 lines (110 loc) · 7.19 KB
title Graph Model
order 6

Graph Model

NeoWiki projects its data into a Neo4j graph for querying (ADR 3). The graph is a secondary store; the source of truth is the MediaWiki revision slots it is built from (ADR 4).

For definitions of domain terms like Subject, Statement, and Schema, see the Glossary.

Overview

Two node types and two relationship categories:

(:Page)-[:HasSubject {isMain}]->(:Subject:SchemaName)
(:Subject)-[:RelationType {id, ...}]->(:Subject)

Page Nodes

Every page is projected as a :Page node when it is saved and by RebuildGraphDatabases.php, whether or not it holds Subjects. A failed projection leaves the page with no node, or with one holding an earlier revision's data.

A shared graph can hold pages from multiple wikis (a wiki farm), and MediaWiki page ids are unique only within a wiki, so a page is identified by the (wiki_id, id) pair, not id alone (ADR 22). A single-wiki install has just one wiki_id.

Property Neo4j Type Description
wiki_id string MediaWiki Wiki ID (database name + table prefix) of the owning wiki
id integer MediaWiki page ID (unique per wiki)
name string Full page title, including the namespace prefix (e.g. Help:Installation)
namespaceId integer MediaWiki namespace ID of the page (e.g. 0 for the main namespace, 12 for Help)
creationTime datetime When the page was created
lastUpdated datetime When the page was last modified
lastEditor string Username of the last editor
categories string[] MediaWiki categories the page belongs to

Built-in namespaces have the same ID on every wiki, so namespaceId filters consistently across a shared graph. Custom namespaces ($wgExtraNamespaces) get per-wiki IDs whose meaning can differ between wikis; pair namespaceId with wiki_id to filter those unambiguously.

Subject Nodes

Each Subject stored on a page gets a :Subject node. Subject nodes carry two labels: Subject and the name of their Schema (e.g. :Subject:Person, :Subject:Company). The Schema label changes if a Subject's type changes.

Fixed properties

Property Neo4j Type Description
id string Subject ID, 15 characters starting with s (unique)
name string Subject label
wiki_id string MediaWiki Wiki ID of the wiki that owns the Subject

Unlike page ids, Subject ids are globally unique nanoids (ADR 14), so a Subject's identity is its id alone. The wiki_id is carried only for per-wiki query filtering in a shared graph.

Dynamic properties

Each non-relation Statement becomes a node property keyed by its Property Name. A number Statement with Property Name "Founded at" and value 2019 becomes the node property Founded at: 2019. A key that is not a valid Cypher identifier must be backtick-escaped when read (s.`Founded at`).

The PropertyType determines the value's Neo4j type:

PropertyType Neo4j value
text, url, select list of strings
number integer or float
boolean boolean
date list of dates
dateTime list of datetimes
relation stored as a relationship, not a node property

A Property Name that collides with a fixed property (id, name, wiki_id) does not override it: the fixed value wins and the Statement's value is not projected.

Values a PropertyType cannot represent are dropped from the projection: a property whose type has no registered PropertyType produces no node property, and non-ISO 8601 date/dateTime parts are omitted from the stored value. The revision slot stays authoritative.

Stub Subject nodes

A Subject node can exist as a stub: a node stripped down to only its id and wiki_id properties and the Subject label — no name, no Schema label, and no Statement-derived properties. A stub keeps a Subject's identity available for incoming relations while carrying none of its data.

Stubs arise in two ways:

  • Referenced but removed. When a Subject is removed from its page (or its page is deleted) but other Subjects still hold relations to it, its node is reduced to a stub rather than deleted, and its HasSubject and outgoing relationships are removed. This keeps the incoming references valid.
  • Referenced but not yet created. When a Relation targets a Subject that does not exist yet, a stub target node is created so the relationship can be stored.

When the real Subject is later saved, its node is upgraded in place: the stub gains its properties and Schema label, and no duplicate node is created.

A write that strips a stub of its last incoming relation deletes the stub, whether that write removes the referring Subject, drops the Relation, or retargets it. Removing a set of Subjects referenced only by each other leaves none of them behind.

Relationships

HasSubject

Connects a Page node to each of its Subject nodes.

Property Neo4j Type Description
isMain boolean true for the Main Subject, false for Child Subjects

A page can have at most one Main Subject and any number of Child Subjects (ADR 7).

Typed Relations

Subject-to-Subject relationships represent Relations. The relationship type in Neo4j is the Relation Type defined in the Property Definition (e.g. Has author, Has product). Names that are not valid Cypher identifiers are backtick-escaped.

Property Neo4j Type Description
id string Relation ID, 15 characters starting with r
(additional) scalar Any properties from the Relation's property map

When a Subject is removed while other Subjects still reference it, its node is kept as a stub for as long as those references last.

Constraints

Two node uniqueness constraints apply: (wiki_id, id) on :Page nodes (ADR 22) and id on :Subject nodes. Both are created by update.php and by RebuildGraphDatabases.php, not by the incremental per-edit projection.

Relation (edge) id values carry no uniqueness constraint (#351).

Related Documentation