Module: Familia::Features::Relationships::Indexing

Defined in:
lib/familia/features/relationships/indexing.rb,
lib/familia/features/relationships/indexing/rebuild_strategies.rb,
lib/familia/features/relationships/indexing/multi_index_generators.rb,
lib/familia/features/relationships/indexing/unique_index_generators.rb

Overview

Indexing module for attribute-based lookups using Valkey/Redis data structures. Provides O(1) field-to-object mappings without relationship semantics.

Terminology:

  • unique_index: 1:1 field-to-object mapping (HashKey)
  • multi_index: 1:many field-to-objects mapping (UnsortedSet, no scores)
  • within: scope class providing uniqueness boundary for instance-scoped indexes
  • query: whether to generate find_by_* methods (default: true)

Key Patterns:

  • Class unique: "user:email_index" → HashKey
  • Instance unique: "company:c1:badge_index" → HashKey
  • Instance multi: "company:c1:dept_index:engineering" → UnsortedSet

Auto-Indexing: Class-level unique_index declarations automatically populate on save(): user = User.new(email: 'test@example.com') user.save # Auto-indexes email → user_id Instance-scoped indexes (with within:) remain manual (require parent context).

Design Philosophy: Indexing is for finding objects by attribute, not ordering them. Use multi_index with UnsortedSet (no temporal scores), then sort in Ruby: employees = company.find_all_by_department('eng') sorted = employees.sort_by(&:hire_date)

Examples:

Class-level unique index (1:1 mapping via HashKey)

class User < Familia::Horreum
  feature :relationships
  field :email
  unique_index :email, :email_lookup
end

user = User.new(user_id: 'u1', email: 'alice@example.com')
user.save  # Automatically populates email_lookup index
User.find_by_email('alice@example.com')  # → user

Instance-scoped unique index (within parent, 1:1 via HashKey)

class Employee < Familia::Horreum
  feature :relationships
  field :badge_number
  unique_index :badge_number, :badge_index, within: Company
end

company = Company.new(company_id: 'c1')
employee = Employee.new(emp_id: 'e1', badge_number: '12345')
employee.add_to_company_badge_index(company)
company.find_by_badge_number('12345')  # → employee

Instance-scoped multi-value index (within parent, 1:many via UnsortedSet)

class Employee < Familia::Horreum
  feature :relationships
  field :department
  multi_index :department, :dept_index, within: Company
end

company = Company.new(company_id: 'c1')
emp1 = Employee.new(emp_id: 'e1', department: 'engineering')
emp2 = Employee.new(emp_id: 'e2', department: 'engineering')
emp1.add_to_company_dept_index(company)
emp2.add_to_company_dept_index(company)
company.find_all_by_department('engineering')  # → [emp1, emp2]

Defined Under Namespace

Modules: ModelClassMethods, ModelInstanceMethods, MultiIndexGenerators, RebuildStrategies, UniqueIndexGenerators

Class Method Summary collapse

Class Method Details

.included(base) ⇒ Object

Class-level indexing configurations



80
81
82
83
84
# File 'lib/familia/features/relationships/indexing.rb', line 80

def self.included(base)
  base.extend ModelClassMethods
  base.include ModelInstanceMethods
  super
end