Module: Mongoid::SearchIndexable::ClassMethods
- Defined in:
- lib/mongoid/search_indexable.rb
Overview
Implementations for the feature's class-level methods.
Instance Method Summary collapse
-
#auto_embed_search(text, index: nil, path: nil, limit: 10, num_candidates: nil, filter: nil, exact: false, model: nil, pipeline: []) ⇒ Array<Mongoid::Document>
Performs an Atlas Vector Search query using auto-embedding.
-
#create_search_indexes ⇒ Array<String>
Request the creation of all registered search indices.
-
#remove_search_index(name: nil, id: nil) ⇒ Object
Removes the search index specified by the given name or id.
-
#remove_search_indexes ⇒ Object
Request the removal of all registered search indexes.
-
#search_index(name_or_defn, defn = nil) ⇒ Object
Adds an index definition for the provided single or compound keys.
-
#search_indexes(options = {}) ⇒ Object
A convenience method for querying the search indexes available on the current model's collection.
-
#vector_search(vector, index: nil, path: nil, limit: 10, num_candidates: nil, exact: false, filter: nil, pipeline: []) ⇒ Array<Mongoid::Document>
Performs an Atlas Vector Search query and returns matching documents.
-
#vector_search_index(name_or_defn, defn = nil) ⇒ Object
Adds a vector search index definition.
-
#wait_for_search_indexes(names, interval: 5) {|SearchIndexable::Status| ... } ⇒ Object
Waits for the named search indexes to be created.
Instance Method Details
#auto_embed_search(text, index: nil, path: nil, limit: 10, num_candidates: nil, filter: nil, exact: false, model: nil, pipeline: []) ⇒ Array<Mongoid::Document>
Performs an Atlas Vector Search query using auto-embedding. Atlas generates the query vector from the supplied text at query time; no pre-computed embedding is required.
Each returned document has a vector_search_score attribute populated
with its relevance score. Unlike vector_search, the indexed text field
is retained in returned documents.
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/mongoid/search_indexable.rb', line 378 def (text, index: nil, path: nil, limit: 10, num_candidates: nil, filter: nil, exact: false, model: nil, pipeline: []) # rubocop:disable Metrics/ParameterLists resolved_index, resolved_path = (index, path) = { 'index' => resolved_index, 'path' => resolved_path, 'query' => { 'text' => text }, 'limit' => limit } ['numCandidates'] = num_candidates || (limit * 10) unless exact ['exact'] = true if exact ['filter'] = filter if filter ['model'] = model if model agg_pipeline = [ { '$vectorSearch' => }, { '$addFields' => { 'vector_search_score' => { '$meta' => 'vectorSearchScore' } } } ] agg_pipeline.concat(Array(pipeline)) collection.aggregate(agg_pipeline).map { |doc| instantiate(doc) } end |
#create_search_indexes ⇒ Array<String>
Request the creation of all registered search indices. Note that the search indexes are created asynchronously, and may take several minutes to be fully available.
161 162 163 164 165 166 167 |
# File 'lib/mongoid/search_indexable.rb', line 161 def create_search_indexes return if search_index_specs.empty? Threaded.with_collection_management do collection.search_indexes.create_many(search_index_specs) end end |
#remove_search_index(name: nil, id: nil) ⇒ Object
Removes the search index specified by the given name or id. Either name OR id must be given, but not both.
207 208 209 210 211 212 213 214 215 216 |
# File 'lib/mongoid/search_indexable.rb', line 207 def remove_search_index(name: nil, id: nil) Threaded.with_collection_management do logger.info( "MONGOID: Removing search index '#{name || id}' " \ "on collection '#{collection.name}'." ) collection.search_indexes.drop_one(name: name, id: id) end end |
#remove_search_indexes ⇒ Object
It would be nice if this could remove ONLY the search indexes
Request the removal of all registered search indexes. Note that the search indexes are removed asynchronously, and may take several minutes to be fully deleted.
that have been declared on the model, but because the model may not name the index, we can't guarantee that we'll know the name or id of the corresponding indexes. It is not unreasonable to assume, though, that the intention is for the model to declare, one-to-one, all desired search indexes, so removing all search indexes ought to suffice. If a specific index or set of indexes needs to be removed instead, consider using search_indexes.each with remove_search_index.
230 231 232 233 234 |
# File 'lib/mongoid/search_indexable.rb', line 230 def remove_search_indexes search_indexes.each do |spec| remove_search_index id: spec['id'] end end |
#search_index(name_or_defn, defn = nil) ⇒ Object
Adds an index definition for the provided single or compound keys.
249 250 251 252 253 254 255 |
# File 'lib/mongoid/search_indexable.rb', line 249 def search_index(name_or_defn, defn = nil) name = name_or_defn name, defn = nil, name if name.is_a?(Hash) spec = { definition: defn }.tap { |s| s[:name] = name.to_s if name } search_index_specs.push(spec) end |
#search_indexes(options = {}) ⇒ Object
A convenience method for querying the search indexes available on the current model's collection.
196 197 198 199 200 |
# File 'lib/mongoid/search_indexable.rb', line 196 def search_indexes( = {}) Threaded.with_collection_management do collection.search_indexes() end end |
#vector_search(vector, index: nil, path: nil, limit: 10, num_candidates: nil, exact: false, filter: nil, pipeline: []) ⇒ Array<Mongoid::Document>
Performs an Atlas Vector Search query and returns matching documents.
Each returned document has a vector_search_score attribute populated
with its relevance score.
The vector field (given by path:) is excluded from the returned
documents by default, as vectors are large and rarely useful after
retrieval.
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/mongoid/search_indexable.rb', line 324 def vector_search(vector, index: nil, path: nil, limit: 10, num_candidates: nil, exact: false, filter: nil, pipeline: []) # rubocop:disable Metrics/ParameterLists resolved_index, resolved_path = resolve_vector_index(index, path) = { 'index' => resolved_index, 'path' => resolved_path, 'queryVector' => vector, 'limit' => limit } ['numCandidates'] = num_candidates || (limit * 10) unless exact ['exact'] = true if exact ['filter'] = filter if filter agg_pipeline = [ { '$vectorSearch' => }, { '$addFields' => { 'vector_search_score' => { '$meta' => 'vectorSearchScore' } } }, { '$project' => { resolved_path => 0 } } ] agg_pipeline.concat(Array(pipeline)) collection.aggregate(agg_pipeline).map { |doc| instantiate(doc) } end |
#vector_search_index(name_or_defn, defn = nil) ⇒ Object
Adds a vector search index definition. Also defines a read-only
vector_search_score field on the model the first time it is called,
which is populated on documents returned by vector_search.
280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/mongoid/search_indexable.rb', line 280 def vector_search_index(name_or_defn, defn = nil) name = name_or_defn name, defn = nil, name if name.is_a?(Hash) validate_vector_index_definition!(defn) spec = { type: 'vectorSearch', definition: defn }.tap { |s| s[:name] = name.to_s if name } search_index_specs.push(spec) return if fields.key?('vector_search_score') field :vector_search_score, type: Float attr_readonly :vector_search_score end |
#wait_for_search_indexes(names, interval: 5) {|SearchIndexable::Status| ... } ⇒ Object
Waits for the named search indexes to be created.
176 177 178 179 180 181 182 183 184 |
# File 'lib/mongoid/search_indexable.rb', line 176 def wait_for_search_indexes(names, interval: 5) loop do status = Status.new(get_indexes(names)) yield status if block_given? break if status.ready? sleep interval end end |