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