GroupKey class

Annotation for GroupIndex key classes that organize root resources into logical groups for partitioned indexing.

Important: GroupKey does not define a new RDF type. It is a framework construct used to organize resources into hierarchical groups (e.g., by date, category, tag). Group keys are typically represented as blank nodes or use the standard idx:GroupKey framework type.

This contrasts with RootResource, SubResource, and LocalResource, which define semantic domain types. GroupKey is purely organizational.

Concept

Group keys partition a large set of resources into smaller groups for performance and selective synchronization. Each group has:

  • A unique key value derived from resource properties (via groupingProperties)
  • A separate index containing only resources in that group
  • Independent synchronization and caching

Basic Example

@RootResource(PersonalNotesVocab.Note, ...)
class Note {
  @RdfProperty(Schema.name)
  String? title;

  @RdfProperty(Schema.dateCreated)
  DateTime? createdAt;
}

// Group notes by creation month (e.g., "2025-01", "2025-02")
@GroupKey(
  Note,
  localName: 'byMonth',
  groupingProperties: [
    GroupingProperty(
      Schema.dateCreated,
      transforms: [
        RegexTransform(r'^(\d{4}-\d{2})', r'\1'),  // Extract YYYY-MM
      ],
    ),
  ],
)
class NoteMonthGroupKey {
  @RdfProperty(Schema.dateCreated)
  String? month;  // "2025-01"
}

Resource Type Reference

The resourceType parameter references the RootResource type this group index organizes. The generator uses this to:

  • Link the group index configuration to the correct resource type
  • Generate type-safe query APIs
  • Configure index synchronization

Local Name

The optional localName distinguishes multiple group indices for the same resource type:

  • localName: 'byMonth' → group by month
  • localName: 'byCategory' → group by category
  • Default: 'default' if omitted

Grouping Properties

groupingProperties defines how group key values are derived from resource properties:

groupingProperties: [
  // Extract year-month from DateTime (YYYY-MM)
  GroupingProperty(
    Schema.dateCreated,
    transforms: [RegexTransform(r'^(\d{4}-\d{2})', r'\1')],
  ),
  // Use property as-is without transformation
  GroupingProperty(PersonalNotesVocab.category),
]

Multiple properties create hierarchical group keys (e.g., "work/2025-01").

Custom Vocabulary Properties

Group keys can use properties from custom vocabularies:

// Define custom vocabulary
const appVocab = AppVocab(
  appBaseUri: 'https://myapp.example.com/',
  vocabPath: 'vocabulary/myapp',
);

class MyAppProperties {
  static const channelId = IriTerm('https://myapp.example.com/vocabulary/myapp#channelId');
  static const timestamp = IriTerm('https://myapp.example.com/vocabulary/myapp#timestamp');
}

// Root resource - generator creates vocabulary properties
@RootResource(appVocab, ...)
class Message {
  @RdfProperty(Schema.text)
  String? content;

  @RdfProperty.define()  // Generated: myapp:channelId
  String? channelId;

  // Generated: myapp:timestamp - @RdfProperty.define() is optional
  DateTime? timestamp;
}

// Group by channel and month using custom properties
@GroupKey(
  Message,
  localName: 'byChannelAndMonth',
  groupingProperties: [
    GroupingProperty(MyAppProperties.channelId),
    GroupingProperty(
      MyAppProperties.timestamp,
      transforms: [
        RegexTransform(r'^(\d{4}-\d{2})', r'\1'),  // Extract YYYY-MM
      ],
    ),
  ],
)
class MessageChannelMonthGroupKey {
  @RdfProperty(MyAppProperties.channelId)
  String? channelId;

  @RdfProperty(MyAppProperties.timestamp)
  DateTime? yearMonth;  // Normalized to first UTC instant of month
}

Advanced: Multi-Level Grouping

@GroupKey(
  Note,
  localName: 'byCategoryAndMonth',
  groupingProperties: [
    GroupingProperty(PersonalNotesVocab.category),  // First level
    GroupingProperty(
      Schema.dateCreated,
      transforms: [RegexTransform(r'^(\d{4}-\d{2})', r'\1')],  // Extract YYYY-MM
    ),
  ],
)
class NoteCategoryMonthGroupKey {
  @RdfProperty(PersonalNotesVocab.category)
  String? category;

  @RdfProperty(Schema.dateCreated)
  String? month;
}

This creates group keys like "work/2025-01", "personal/2025-02".

RDF Representation

Group keys do not create app-specific RDF types. They use framework infrastructure (blank nodes or idx:GroupKey) for organization.

Code Generation

The generator creates:

  • GroupIndex configuration in LocordaConfig
  • Type-safe query APIs for accessing groups
  • Index synchronization logic

See Also

Inheritance
Implemented types

Constructors

GroupKey(Type resourceType, {String? localName, List<GroupingProperty> groupingProperties = const []})
Creates a GroupKey annotation for organizing resources into groups.
const

Properties

classIri → IriTerm?
The RDF class IRI for this blank node.
finalinherited
comment String?
Optional description for this class in define mode.
finalinherited
direction MapperDirection?
Specifies whether this mapper should handle serialization, deserialization, or both.
finalinherited
fragment String?
The fragment identifier for vocabulary generation mode.
finalinherited
groupingProperties List<GroupingProperty>
Grouping property definitions with optional transforms.
final
hashCode int
The hash code for this object.
no setterinherited
label String?
Optional human-readable label for this class in define mode.
finalinherited
localName String?
Local name for this group index (default: 'default').
final
mapper MapperRef<LocalResourceMapper>?
Provides a MapperRef if a custom mapper is specified.
no setterinherited
metadata List<(IriTerm, RdfObject)>?
Optional additional metadata triples for this class in define mode.
finalinherited
registerGlobally bool
Controls whether the generated mapper should be registered globally in the initRdfMapper function.
finalinherited
resourceType Type
The resource type this group index is for.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
subClassOf → IriTerm?
The superclass for this resource in define mode.
finalinherited
vocab AppVocab?
The vocabulary configuration for define mode.
finalinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited