Class: FactDb::Services::SourceService
- Inherits:
-
Object
- Object
- FactDb::Services::SourceService
- Defined in:
- lib/fact_db/services/source_service.rb
Overview
Service class for managing source documents in the database
Provides methods for creating, searching, and retrieving source documents which are the original content from which facts are extracted.
Instance Attribute Summary collapse
-
#config ⇒ FactDb::Config
readonly
The configuration object.
Instance Method Summary collapse
-
#between(from, to) ⇒ ActiveRecord::Relation
Returns sources captured between two dates.
-
#by_kind(kind, limit: nil) ⇒ ActiveRecord::Relation
Returns sources of a specific kind.
-
#create(content, kind:, captured_at: Time.current, metadata: {}, title: nil, source_uri: nil) ⇒ FactDb::Models::Source
Creates a new source document in the database.
-
#find(id) ⇒ FactDb::Models::Source
Finds a source by ID.
-
#find_by_hash(hash) ⇒ FactDb::Models::Source?
Finds a source by content hash.
-
#initialize(config = FactDb.config) ⇒ SourceService
constructor
Initializes a new SourceService instance.
-
#recent(limit: 10) ⇒ ActiveRecord::Relation
Returns recently captured sources.
-
#search(query, kind: nil, from: nil, to: nil, limit: 20) ⇒ ActiveRecord::Relation
Searches sources using full-text search with optional filters.
-
#semantic_search(query, limit: 20) ⇒ ActiveRecord::Relation
Searches sources using semantic similarity (vector search).
-
#stats ⇒ Hash
Returns aggregate statistics about sources.
Constructor Details
#initialize(config = FactDb.config) ⇒ SourceService
Initializes a new SourceService instance
21 22 23 |
# File 'lib/fact_db/services/source_service.rb', line 21 def initialize(config = FactDb.config) @config = config end |
Instance Attribute Details
#config ⇒ FactDb::Config (readonly)
Returns the configuration object.
16 17 18 |
# File 'lib/fact_db/services/source_service.rb', line 16 def config @config end |
Instance Method Details
#between(from, to) ⇒ ActiveRecord::Relation
Returns sources captured between two dates
126 127 128 |
# File 'lib/fact_db/services/source_service.rb', line 126 def between(from, to) Models::Source.captured_between(from, to).order(captured_at: :asc) end |
#by_kind(kind, limit: nil) ⇒ ActiveRecord::Relation
Returns sources of a specific kind
115 116 117 118 119 |
# File 'lib/fact_db/services/source_service.rb', line 115 def by_kind(kind, limit: nil) scope = Models::Source.by_kind(kind).order(captured_at: :desc) scope = scope.limit(limit) if limit scope end |
#create(content, kind:, captured_at: Time.current, metadata: {}, title: nil, source_uri: nil) ⇒ FactDb::Models::Source
Creates a new source document in the database
Automatically deduplicates by content hash - returns existing source if content matches.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/fact_db/services/source_service.rb', line 42 def create(content, kind:, captured_at: Time.current, metadata: {}, title: nil, source_uri: nil) content_hash = Digest::SHA256.hexdigest(content) # Check for duplicate content existing = Models::Source.find_by(content_hash: content_hash) return existing if existing = (content) Models::Source.create!( content: content, content_hash: content_hash, kind: kind.to_s, title: title, source_uri: source_uri, metadata: , captured_at: captured_at, embedding: ) end |
#find(id) ⇒ FactDb::Models::Source
Finds a source by ID
68 69 70 |
# File 'lib/fact_db/services/source_service.rb', line 68 def find(id) Models::Source.find(id) end |
#find_by_hash(hash) ⇒ FactDb::Models::Source?
Finds a source by content hash
76 77 78 |
# File 'lib/fact_db/services/source_service.rb', line 76 def find_by_hash(hash) Models::Source.find_by(content_hash: hash) end |
#recent(limit: 10) ⇒ ActiveRecord::Relation
Returns recently captured sources
134 135 136 |
# File 'lib/fact_db/services/source_service.rb', line 134 def recent(limit: 10) Models::Source.order(captured_at: :desc).limit(limit) end |
#search(query, kind: nil, from: nil, to: nil, limit: 20) ⇒ ActiveRecord::Relation
Searches sources using full-text search with optional filters
88 89 90 91 92 93 94 |
# File 'lib/fact_db/services/source_service.rb', line 88 def search(query, kind: nil, from: nil, to: nil, limit: 20) scope = Models::Source.search_text(query) scope = scope.by_kind(kind) if kind scope = scope.captured_after(from) if from scope = scope.captured_before(to) if to scope.order(captured_at: :desc).limit(limit) end |
#semantic_search(query, limit: 20) ⇒ ActiveRecord::Relation
Searches sources using semantic similarity (vector search)
Requires an embedding generator to be configured.
103 104 105 106 107 108 |
# File 'lib/fact_db/services/source_service.rb', line 103 def semantic_search(query, limit: 20) = (query) return Models::Source.none unless Models::Source.nearest_neighbors(, limit: limit) end |
#stats ⇒ Hash
Returns aggregate statistics about sources
141 142 143 144 145 146 147 148 149 150 |
# File 'lib/fact_db/services/source_service.rb', line 141 def stats { total: Models::Source.count, total_count: Models::Source.count, by_kind: Models::Source.group(:kind).count, earliest: Models::Source.minimum(:captured_at), latest: Models::Source.maximum(:captured_at), total_words: Models::Source.sum("array_length(regexp_split_to_array(content, '\\s+'), 1)") } end |