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 +4 -4
- data/lib/search_engine/relation/dsl/vectors.rb +44 -5
- data/lib/search_engine/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 228f70410334d2a324508d0d44dfd31aadbcb4a957f28425909108490a3129a2
|
|
4
|
+
data.tar.gz: 89fd3243af9aec91757d9819136ce9b0fd783845ff1ff6e6fe72467106d20ecb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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
|
|
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
|