Class: Expressir::Model::SearchEngine

Inherits:
Object
  • Object
show all
Defined in:
lib/expressir/model/search_engine.rb

Overview

SearchEngine for querying EXPRESS elements in a repository Handles pattern matching, wildcards, regex, and element collection

Constant Summary collapse

ELEMENT_TYPES =

Element types that can be searched

%w[
  schema entity type attribute derived_attribute inverse_attribute
  function procedure rule constant parameter variable
  where_rule unique_rule enumeration_item interface
].freeze
TYPE_CATEGORIES =

Type categories for filtering

%w[select enumeration aggregate defined].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repository) ⇒ SearchEngine

Initialize search engine with a repository

Parameters:

  • repository (Repository)

    Repository to search



22
23
24
25
# File 'lib/expressir/model/search_engine.rb', line 22

def initialize(repository)
  @repository = repository
  @repository.build_indexes if @repository.entity_index.nil?
end

Instance Attribute Details

#repositoryObject (readonly)

Returns the value of attribute repository.



18
19
20
# File 'lib/expressir/model/search_engine.rb', line 18

def repository
  @repository
end

Instance Method Details

#count(type:, schema: nil, category: nil) ⇒ Integer

Count elements matching criteria

Parameters:

  • type (String)

    Element type

  • schema (String, nil) (defaults to: nil)

    Filter by schema

  • category (String, nil) (defaults to: nil)

    Type category filter

Returns:

  • (Integer)

    Count of elements



78
79
80
# File 'lib/expressir/model/search_engine.rb', line 78

def count(type:, schema: nil, category: nil)
  collect_elements(type: type, schema: schema, category: category).size
end

#list(type:, schema: nil, category: nil) ⇒ Array<Hash>

List all elements of a specific type

Parameters:

  • type (String)

    Element type to list

  • schema (String, nil) (defaults to: nil)

    Filter by schema name

  • category (String, nil) (defaults to: nil)

    Type category filter (for type elements)

Returns:

  • (Array<Hash>)

    List of elements



32
33
34
35
36
# File 'lib/expressir/model/search_engine.rb', line 32

def list(type:, schema: nil, category: nil)
  elements = collect_elements(type: type, schema: schema,
                              category: category)
  elements.map { |elem| element_to_hash(elem, type) }
end

#search(pattern:, type: nil, schema: nil, category: nil, case_sensitive: false, regex: false, exact: false) ⇒ Array<Hash>

Search for elements matching a pattern

Parameters:

  • pattern (String)

    Search pattern

  • type (String, nil) (defaults to: nil)

    Filter by element type

  • schema (String, nil) (defaults to: nil)

    Limit to specific schema

  • category (String, nil) (defaults to: nil)

    Type category filter

  • case_sensitive (Boolean) (defaults to: false)

    Enable case-sensitive matching

  • regex (Boolean) (defaults to: false)

    Treat pattern as regex

  • exact (Boolean) (defaults to: false)

    Exact match only

Returns:

  • (Array<Hash>)

    Matching elements



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/expressir/model/search_engine.rb', line 47

def search(pattern:, type: nil, schema: nil, category: nil,
           case_sensitive: false, regex: false, exact: false)
  # Parse pattern
  pattern_parts = parse_pattern(pattern, case_sensitive: case_sensitive)

  # Determine types to search
  types_to_search = type ? [type] : ELEMENT_TYPES

  # Collect all matching elements
  results = []
  types_to_search.each do |elem_type|
    elements = collect_elements(type: elem_type, schema: schema,
                                category: category)

    elements.each do |elem|
      if matches_pattern?(elem, pattern_parts, elem_type,
                          case_sensitive: case_sensitive,
                          regex: regex, exact: exact)
        results << element_to_hash(elem, elem_type)
      end
    end
  end

  results
end

#search_advanced(pattern:, max_depth: nil, ranked: false, **options) ⇒ Array<Hash>

Advanced search with multiple filters

Parameters:

  • pattern (String)

    Search pattern

  • max_depth (Integer, nil) (defaults to: nil)

    Maximum path depth

  • ranked (Boolean) (defaults to: false)

    Enable relevance ranking

  • options (Hash)

    Additional filters and search options

Returns:

  • (Array<Hash>)

    Filtered and optionally ranked results



111
112
113
114
115
116
117
118
# File 'lib/expressir/model/search_engine.rb', line 111

def search_advanced(pattern:, max_depth: nil, ranked: false, **options)
  results = search(pattern: pattern, **options)

  results = filter_by_depth(results, max_depth) if max_depth
  results = rank_results(results, pattern, 10, 5) if ranked

  results
end

#search_ranked(pattern:, boost_exact: 10, boost_prefix: 5, **options) ⇒ Array<Hash>

Search with relevance ranking

Parameters:

  • pattern (String)

    Search pattern

  • boost_exact (Integer) (defaults to: 10)

    Score boost for exact matches

  • boost_prefix (Integer) (defaults to: 5)

    Score boost for prefix matches

  • options (Hash)

    Additional search options

Returns:

  • (Array<Hash>)

    Ranked results with :relevance_score



100
101
102
103
# File 'lib/expressir/model/search_engine.rb', line 100

def search_ranked(pattern:, boost_exact: 10, boost_prefix: 5, **options)
  results = search(pattern: pattern, **options)
  rank_results(results, pattern, boost_exact, boost_prefix)
end

#search_with_depth(pattern:, max_depth:, **options) ⇒ Array<Hash>

Search with depth filtering

Parameters:

  • pattern (String)

    Search pattern

  • max_depth (Integer)

    Maximum path depth (1=schema, 2=entity, 3=attribute)

  • options (Hash)

    Additional search options

Returns:

  • (Array<Hash>)

    Filtered results



87
88
89
90
91
92
# File 'lib/expressir/model/search_engine.rb', line 87

def search_with_depth(pattern:, max_depth:, **options)
  return [] if max_depth <= 0

  results = search(pattern: pattern, **options)
  filter_by_depth(results, max_depth)
end