search-engine-for-typesense 30.1.6.2 → 30.1.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea3e7da2359ce1d9b4990147c6627e00a726cfa4e75cc340649ae561b32e42fe
4
- data.tar.gz: 6b14b6b9e39cab91210e16ecced55f19948831d9f949cb2969f0be5731229cf1
3
+ metadata.gz: 228f70410334d2a324508d0d44dfd31aadbcb4a957f28425909108490a3129a2
4
+ data.tar.gz: 89fd3243af9aec91757d9819136ce9b0fd783845ff1ff6e6fe72467106d20ecb
5
5
  SHA512:
6
- metadata.gz: 6c2252a8d88ebe47b54bb7ac7ed2d65f2e0ed82b3e011ffeb3f5fb3756bff75de417c055a1de8c71fa513e51a6cfcb70b1025e6463164ff5de7018b1fcec1df8
7
- data.tar.gz: 5519c44a440ed906df1673baf2682b1630171c0a2efb103feeb3300700d2d2653d521432fa332d2bc344c2cf717ba0ae7aa4d3feaaa6dcc7c82cfc0ba1486a4f
6
+ metadata.gz: 42e556e2b25d40fd5ba85cb1ae1961223420d6affb6f532936642a48159dc013a8297398cba3724ef798f2cab05a0819140c9038d415b0035c7f9a95b2408e07
7
+ data.tar.gz: ea3aba9866079ade74da2712d73f6e2a7169cc0a013dff5814ccbc7034789e9f2d6ae38979e49761210e46e4a61f329fde3ae9bb356f02b643b14899a0d24d9d
@@ -11,8 +11,10 @@ module SearchEngine
11
11
  # Perform a vector (semantic / hybrid / ANN) search on an embedding field.
12
12
  #
13
13
  # Last call wins — Typesense supports a single `vector_query` per search.
14
+ # When +field+ is omitted the sole embedding declared on the model is
15
+ # used automatically; raises when the model has zero or multiple embeddings.
14
16
  #
15
- # @param field [Symbol, String] embedding field name
17
+ # @param field [Symbol, String, nil] embedding field name (auto-resolved when nil)
16
18
  # @param k [Integer, nil] number of nearest neighbors
17
19
  # @param alpha [Float, nil] hybrid blend weight (0.0 = keyword, 1.0 = vector)
18
20
  # @param query [Array<Numeric>, nil] explicit embedding vector
@@ -24,11 +26,12 @@ module SearchEngine
24
26
  # @param ef [Integer, nil] HNSW ef override
25
27
  # @param flat_search_cutoff [Integer, nil] brute-force threshold
26
28
  # @return [SearchEngine::Relation]
27
- def vector_search(field, k: nil, alpha: nil, query: nil, id: nil,
29
+ def vector_search(field = nil, k: nil, alpha: nil, query: nil, id: nil,
28
30
  distance_threshold: nil, queries: nil, weights: nil,
29
31
  ef: nil, flat_search_cutoff: nil)
32
+ resolved = resolve_vector_field(field)
30
33
  normalized = normalize_vector_search(
31
- field, k: k, alpha: alpha, query: query, id: id,
34
+ resolved, k: k, alpha: alpha, query: query, id: id,
32
35
  distance_threshold: distance_threshold, queries: queries,
33
36
  weights: weights, ef: ef, flat_search_cutoff: flat_search_cutoff
34
37
  )
@@ -38,13 +41,15 @@ module SearchEngine
38
41
  # Find documents similar to a given document ID.
39
42
  #
40
43
  # Sugar over `vector_search` with `id:`.
44
+ # When +field+ is omitted the sole embedding declared on the model is
45
+ # used automatically (same resolution as {#vector_search}).
41
46
  #
42
47
  # @param document_id [#to_s] ID of the reference document
43
- # @param field [Symbol, String] embedding field name
48
+ # @param field [Symbol, String, nil] embedding field name (auto-resolved when nil)
44
49
  # @param k [Integer, nil] number of nearest neighbors
45
50
  # @param distance_threshold [Float, nil] max cosine distance
46
51
  # @return [SearchEngine::Relation]
47
- def find_similar(document_id, field:, k: nil, distance_threshold: nil)
52
+ def find_similar(document_id, field: nil, k: nil, distance_threshold: nil)
48
53
  vector_search(field, id: document_id, k: k, distance_threshold: distance_threshold)
49
54
  end
50
55
 
@@ -297,6 +302,40 @@ module SearchEngine
297
302
  )
298
303
  end
299
304
 
305
+ # -- Field resolution ---------------------------------------------------
306
+
307
+ # Auto-resolve the embedding field when none is given explicitly.
308
+ # Returns the field as-is when provided, or the sole embedding field
309
+ # declared on the model. Raises when resolution is ambiguous or impossible.
310
+ #
311
+ # @param field [Symbol, String, nil] explicit field or nil for auto-resolution
312
+ # @return [Symbol, String]
313
+ def resolve_vector_field(field)
314
+ return field unless field.nil?
315
+
316
+ embeddings = vector_embeddings_map
317
+ case embeddings.size
318
+ when 1
319
+ embeddings.each_key.first
320
+ when 0
321
+ raise SearchEngine::Errors::InvalidVectorQuery.new(
322
+ "InvalidVectorQuery: cannot auto-resolve embedding field \u2014 " \
323
+ "no embeddings declared on #{klass_name_for_inspect}",
324
+ hint: 'Declare one with `embedding` in your model DSL',
325
+ doc: VECTOR_SEARCH_DOC_URL
326
+ )
327
+ else
328
+ fields_list = embeddings.keys.map { |k| ":#{k}" }.join(', ')
329
+ raise SearchEngine::Errors::InvalidVectorQuery.new(
330
+ "InvalidVectorQuery: cannot auto-resolve embedding field \u2014 " \
331
+ "#{klass_name_for_inspect} has multiple embeddings (#{fields_list})",
332
+ hint: 'Pass the field explicitly: .vector_search(:field_name)',
333
+ doc: VECTOR_SEARCH_DOC_URL,
334
+ details: { available_embeddings: embeddings.keys }
335
+ )
336
+ end
337
+ end
338
+
300
339
  # -- Helpers ------------------------------------------------------------
301
340
 
302
341
  def vector_embeddings_map
@@ -3,5 +3,5 @@
3
3
  module SearchEngine
4
4
  # Current gem version.
5
5
  # @return [String]
6
- VERSION = '30.1.6.2'
6
+ VERSION = '30.1.6.3'
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search-engine-for-typesense
3
3
  version: !ruby/object:Gem::Version
4
- version: 30.1.6.2
4
+ version: 30.1.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shkoda