search-engine-for-typesense 1.0.2 → 30.1.1
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/README.md +12 -6
- data/app/search_engine/search_engine/index_partition_job.rb +7 -26
- data/lib/generators/search_engine/install/install_generator.rb +1 -1
- data/lib/generators/search_engine/install/templates/initializer.rb.tt +11 -11
- data/lib/generators/search_engine/model/model_generator.rb +2 -2
- data/lib/generators/search_engine/model/templates/model.rb.tt +2 -2
- data/lib/search_engine/admin/stopwords.rb +1 -1
- data/lib/search_engine/admin/synonyms.rb +1 -1
- data/lib/search_engine/ast/node.rb +1 -1
- data/lib/search_engine/ast.rb +1 -1
- data/lib/search_engine/base/creation.rb +4 -4
- data/lib/search_engine/cli/doctor.rb +6 -6
- data/lib/search_engine/client/http_adapter.rb +1 -1
- data/lib/search_engine/client/request_builder.rb +2 -2
- data/lib/search_engine/client/services/base.rb +2 -2
- data/lib/search_engine/client/services/collections.rb +7 -7
- data/lib/search_engine/client/services/documents.rb +11 -7
- data/lib/search_engine/client/services/operations.rb +5 -5
- data/lib/search_engine/client/services/search.rb +3 -3
- data/lib/search_engine/client.rb +201 -46
- data/lib/search_engine/collection_resolver.rb +7 -2
- data/lib/search_engine/config/presets.rb +7 -7
- data/lib/search_engine/config.rb +5 -5
- data/lib/search_engine/console_helpers.rb +4 -4
- data/lib/search_engine/dispatcher.rb +2 -2
- data/lib/search_engine/dsl/parser.rb +9 -9
- data/lib/search_engine/errors.rb +6 -6
- data/lib/search_engine/filters/sanitizer.rb +24 -44
- data/lib/search_engine/hydration/materializers.rb +14 -8
- data/lib/search_engine/indexer/batch_planner.rb +3 -8
- data/lib/search_engine/indexer/import_dispatcher.rb +3 -57
- data/lib/search_engine/indexer/import_response_parser.rb +92 -0
- data/lib/search_engine/indexer/retry_policy.rb +9 -6
- data/lib/search_engine/indexer.rb +4 -235
- data/lib/search_engine/instrumentation.rb +1 -1
- data/lib/search_engine/joins/guard.rb +4 -4
- data/lib/search_engine/joins/resolver.rb +2 -2
- data/lib/search_engine/logging_subscriber.rb +4 -4
- data/lib/search_engine/mapper.rb +13 -21
- data/lib/search_engine/multi.rb +2 -2
- data/lib/search_engine/multi_result.rb +1 -1
- data/lib/search_engine/notifications/compact_logger.rb +3 -3
- data/lib/search_engine/otel.rb +5 -5
- data/lib/search_engine/partitioner.rb +5 -5
- data/lib/search_engine/ranking_plan.rb +4 -4
- data/lib/search_engine/relation/compiler.rb +13 -8
- data/lib/search_engine/relation/dsl/filters.rb +9 -9
- data/lib/search_engine/relation/dsl/selection.rb +3 -3
- data/lib/search_engine/relation/dsl.rb +31 -20
- data/lib/search_engine/relation/dx.rb +4 -4
- data/lib/search_engine/relation/materializers.rb +1 -1
- data/lib/search_engine/relation/options.rb +1 -1
- data/lib/search_engine/relation.rb +1 -1
- data/lib/search_engine/result.rb +1 -1
- data/lib/search_engine/schema.rb +4 -4
- data/lib/search_engine/sources/active_record_source.rb +0 -1
- data/lib/search_engine/sources/lambda_source.rb +1 -1
- data/lib/search_engine/sources/sql_source.rb +1 -1
- data/lib/search_engine/sources.rb +3 -3
- data/lib/search_engine/test/stub_client.rb +8 -8
- data/lib/search_engine/test.rb +2 -2
- data/lib/search_engine/version.rb +1 -1
- data/lib/search_engine.rb +1 -0
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: cc6c98f51d7d42de6bdebe417e43a17bcdda2f4abb89c102277225183466a53e
|
|
4
|
+
data.tar.gz: 511940a80bace746eb5424a756fdc561e34595a6e2867d9f98631eddc669e8a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da964bae21bea332b73a385d1af55ffcc402b443bad34498fca153fa5a4304e784c78ba41a2891c9293204beb9fd653ef8282d5604daa7834584f19695d7cddc
|
|
7
|
+
data.tar.gz: c1fb500960c5849d69c3bcb5f8ee97c2de7d138347889c670df008724166e14ab25bbcadd4c846c05526c49c51f31f7c35061b30609d525b596aa70f2edada96
|
data/README.md
CHANGED
|
@@ -9,6 +9,12 @@ Mountless Rails::Engine for [Typesense](https://typesense.org). Expressive Relat
|
|
|
9
9
|
> [!NOTE]
|
|
10
10
|
> This project is not affiliated with [Typesense](https://typesense.org) and is a wrapper for the [`typesense` gem](https://github.com/typesense/typesense-ruby).
|
|
11
11
|
|
|
12
|
+
## Versioning
|
|
13
|
+
|
|
14
|
+
The gem version mirrors the Typesense server major/minor it targets. Patch releases are reserved for gem-only fixes and enhancements.
|
|
15
|
+
|
|
16
|
+
Example: `30.1.x` targets Typesense `30.1`.
|
|
17
|
+
|
|
12
18
|
## Quickstart
|
|
13
19
|
|
|
14
20
|
```ruby
|
|
@@ -39,7 +45,7 @@ end
|
|
|
39
45
|
SearchEngine::Product.where(name: "milk").select(:id, :name).limit(5).to_a
|
|
40
46
|
```
|
|
41
47
|
|
|
42
|
-
See [Quickstart](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/quickstart).
|
|
48
|
+
See [Quickstart](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/quickstart).
|
|
43
49
|
|
|
44
50
|
### Host app SearchEngine models
|
|
45
51
|
|
|
@@ -117,7 +123,7 @@ SearchEngine::Product.upsert_bulk(data: [mapped])
|
|
|
117
123
|
|
|
118
124
|
## Documentation
|
|
119
125
|
|
|
120
|
-
See the [Docs](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/index)
|
|
126
|
+
See the [Docs](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/index)
|
|
121
127
|
|
|
122
128
|
## Test/offline mode
|
|
123
129
|
|
|
@@ -133,16 +139,16 @@ If you set `SearchEngine.configure { |c| c.client = ... }`, the custom client is
|
|
|
133
139
|
|
|
134
140
|
## Example app
|
|
135
141
|
|
|
136
|
-
See `examples/demo_shop` — demonstrates single/multi search, JOINs, grouping, presets/curation, and DX/observability. Supports offline mode via the stub client (see [Testing](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/testing)).
|
|
142
|
+
See `examples/demo_shop` — demonstrates single/multi search, JOINs, grouping, presets/curation, and DX/observability. Supports offline mode via the stub client (see [Testing](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/testing)).
|
|
137
143
|
|
|
138
144
|
## Contributing
|
|
139
145
|
|
|
140
|
-
See [Docs Style Guide](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/docs-style-guide). Follow YARDoc for public APIs, add backlinks on docs landing pages, and redact secrets in examples.
|
|
146
|
+
See [Docs Style Guide](https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/docs-style-guide). Follow YARDoc for public APIs, add backlinks on docs landing pages, and redact secrets in examples.
|
|
141
147
|
|
|
142
148
|
<!-- Badge references (placeholders) -->
|
|
143
149
|
[ci-badge]: https://img.shields.io/github/actions/workflow/status/lstpsche/search-engine-for-typesense/ci.yml?branch=main
|
|
144
150
|
[ci-url]: #
|
|
145
|
-
[gem-badge]: https://
|
|
151
|
+
[gem-badge]: https://badge.fury.io/rb/search-engine-for-typesense.svg?icon=si%3Arubygems
|
|
146
152
|
[gem-url]: https://rubygems.org/gems/search-engine-for-typesense
|
|
147
153
|
[docs-badge]: https://img.shields.io/badge/docs-index-blue
|
|
148
|
-
[docs-url]: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/index
|
|
154
|
+
[docs-url]: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/index
|
|
@@ -18,7 +18,7 @@ module SearchEngine
|
|
|
18
18
|
rescue_from(SearchEngine::Errors::Timeout) { |error| retry_if_possible(error) }
|
|
19
19
|
rescue_from(SearchEngine::Errors::Connection) { |error| retry_if_possible(error) }
|
|
20
20
|
rescue_from(SearchEngine::Errors::Api) do |error|
|
|
21
|
-
if transient_status?(error.status.to_i)
|
|
21
|
+
if SearchEngine::Indexer::RetryPolicy.transient_status?(error.status.to_i)
|
|
22
22
|
retry_if_possible(error)
|
|
23
23
|
else
|
|
24
24
|
instrument_error(error)
|
|
@@ -82,14 +82,14 @@ module SearchEngine
|
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
def retry_if_possible(error)
|
|
85
|
-
|
|
86
|
-
attempt_no = executions.to_i
|
|
87
|
-
if attempt_no >= attempts
|
|
85
|
+
policy = retry_policy
|
|
86
|
+
attempt_no = executions.to_i
|
|
87
|
+
if attempt_no >= policy.attempts
|
|
88
88
|
instrument_error(error)
|
|
89
89
|
raise
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
wait_seconds =
|
|
92
|
+
wait_seconds = policy.next_delay(attempt_no + 1, error)
|
|
93
93
|
instrument(
|
|
94
94
|
'search_engine.dispatcher.job_error',
|
|
95
95
|
error_payload(error).merge(queue: queue_name, job_id: job_id, retry_after_s: wait_seconds)
|
|
@@ -124,28 +124,9 @@ module SearchEngine
|
|
|
124
124
|
SearchEngine::Instrumentation.instrument(event, payload) {}
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
-
def
|
|
127
|
+
def retry_policy
|
|
128
128
|
cfg = SearchEngine.config.indexer
|
|
129
|
-
|
|
130
|
-
base = cfg&.retries && cfg.retries[:base].to_f.positive? ? cfg.retries[:base].to_f : 0.5
|
|
131
|
-
max = cfg&.retries && cfg.retries[:max].to_f.positive? ? cfg.retries[:max].to_f : 5.0
|
|
132
|
-
jitter = cfg&.retries && cfg.retries[:jitter_fraction].to_f >= 0 ? cfg.retries[:jitter_fraction].to_f : 0.2
|
|
133
|
-
[attempts, base, max, jitter]
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def backoff_seconds(attempt, base:, max:, jitter_fraction:)
|
|
137
|
-
exp = [base * (2 ** (attempt - 1)), max].min
|
|
138
|
-
jitter = exp * jitter_fraction
|
|
139
|
-
delta = rand(-jitter..jitter)
|
|
140
|
-
sleep_time = exp + delta
|
|
141
|
-
sleep_time.positive? ? sleep_time : 0.0
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def transient_status?(code)
|
|
145
|
-
return true if code == 429
|
|
146
|
-
return true if code >= 500 && code <= 599
|
|
147
|
-
|
|
148
|
-
false
|
|
129
|
+
SearchEngine::Indexer::RetryPolicy.from_config(cfg&.retries)
|
|
149
130
|
end
|
|
150
131
|
|
|
151
132
|
def monotonic_ms
|
|
@@ -8,7 +8,7 @@ module SearchEngine
|
|
|
8
8
|
#
|
|
9
9
|
# @example
|
|
10
10
|
# rails g search_engine:install
|
|
11
|
-
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/dx
|
|
11
|
+
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/dx
|
|
12
12
|
class InstallGenerator < Rails::Generators::Base
|
|
13
13
|
source_root File.expand_path('templates', __dir__)
|
|
14
14
|
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
# - Explore queries in `rails console` using SE helpers: `SE.q("milk")`
|
|
12
12
|
#
|
|
13
13
|
# Docs:
|
|
14
|
-
# - Quickstart: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/quickstart
|
|
15
|
-
# - CLI (Doctor): https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/cli
|
|
16
|
-
# - DX helpers: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/dx
|
|
17
|
-
# - Configuration: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/configuration
|
|
14
|
+
# - Quickstart: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/quickstart
|
|
15
|
+
# - CLI (Doctor): https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/cli
|
|
16
|
+
# - DX helpers: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/dx
|
|
17
|
+
# - Configuration: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/configuration
|
|
18
18
|
SearchEngine.configure do |c|
|
|
19
19
|
c.host = ENV.fetch('TYPESENSE_HOST', 'localhost')
|
|
20
20
|
c.port = Integer(ENV.fetch('TYPESENSE_PORT', 8108))
|
|
@@ -83,7 +83,7 @@ SearchEngine.configure do |c|
|
|
|
83
83
|
# c.logger = Rails.logger
|
|
84
84
|
|
|
85
85
|
# --- Presets -------------------------------------------------------------
|
|
86
|
-
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/presets
|
|
86
|
+
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/presets
|
|
87
87
|
|
|
88
88
|
# Enable preset namespacing and resolution. Default: true
|
|
89
89
|
# c.presets.enabled = true
|
|
@@ -95,7 +95,7 @@ SearchEngine.configure do |c|
|
|
|
95
95
|
# c.presets.locked_domains = %i[filter_by sort_by include_fields exclude_fields]
|
|
96
96
|
|
|
97
97
|
# --- Selection & Grouping ------------------------------------------------
|
|
98
|
-
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/field-selection
|
|
98
|
+
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/field-selection
|
|
99
99
|
|
|
100
100
|
# Raise when requested fields are missing during hydration. Default: false
|
|
101
101
|
# c.selection.strict_missing = false
|
|
@@ -104,7 +104,7 @@ SearchEngine.configure do |c|
|
|
|
104
104
|
# c.grouping.warn_on_ambiguous = true
|
|
105
105
|
|
|
106
106
|
# --- Observability & Logging --------------------------------------------
|
|
107
|
-
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/observability
|
|
107
|
+
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/observability
|
|
108
108
|
|
|
109
109
|
# Quiet by default: structured instrumentation logs ([se.*]) are OFF unless
|
|
110
110
|
# explicitly enabled below.
|
|
@@ -129,13 +129,13 @@ SearchEngine.configure do |c|
|
|
|
129
129
|
# c.opentelemetry = { enabled: false, service_name: 'search_engine' }
|
|
130
130
|
|
|
131
131
|
# --- Schema lifecycle ----------------------------------------------------
|
|
132
|
-
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/schema
|
|
132
|
+
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/schema
|
|
133
133
|
|
|
134
134
|
# Retention: how many previous physical collections to keep after swap. Default: 0
|
|
135
135
|
# c.schema.retention.keep_last = 0
|
|
136
136
|
|
|
137
137
|
# --- Indexer -------------------------------------------------------------
|
|
138
|
-
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/indexer
|
|
138
|
+
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/indexer
|
|
139
139
|
|
|
140
140
|
# Default batch size for imports when not provided. Default: 2000
|
|
141
141
|
# c.indexer.batch_size = 2000
|
|
@@ -202,7 +202,7 @@ SearchEngine.configure do |c|
|
|
|
202
202
|
# c.partitioning.max_error_samples = 5
|
|
203
203
|
|
|
204
204
|
# --- Stale deletes -------------------------------------------------------
|
|
205
|
-
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/deletion
|
|
205
|
+
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/deletion
|
|
206
206
|
|
|
207
207
|
# Global kill switch for stale delete workflows. Default: true
|
|
208
208
|
# c.stale_deletes.enabled = true
|
|
@@ -217,7 +217,7 @@ SearchEngine.configure do |c|
|
|
|
217
217
|
# c.stale_deletes.estimation_enabled = false
|
|
218
218
|
|
|
219
219
|
# --- Curation ------------------------------------------------------------
|
|
220
|
-
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/curation
|
|
220
|
+
# See: https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/curation
|
|
221
221
|
|
|
222
222
|
# Maximum number of pinned IDs allowed. Default: 50
|
|
223
223
|
# c.curation.max_pins = 50
|
|
@@ -16,7 +16,7 @@ module SearchEngine
|
|
|
16
16
|
#
|
|
17
17
|
# @example
|
|
18
18
|
# rails g search_engine:model Product --collection products --attrs id:integer name:string
|
|
19
|
-
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/dx
|
|
19
|
+
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/dx
|
|
20
20
|
class ModelGenerator < Rails::Generators::NamedBase
|
|
21
21
|
source_root File.expand_path('templates', __dir__)
|
|
22
22
|
|
|
@@ -31,7 +31,7 @@ module SearchEngine
|
|
|
31
31
|
|
|
32
32
|
raise Thor::Error,
|
|
33
33
|
'--collection is required. See ' \
|
|
34
|
-
'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/dx#generators--console-helpers'
|
|
34
|
+
'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/dx#generators--console-helpers'
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
def create_model
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# Minimal SearchEngine model generated by `search_engine:model`.
|
|
4
4
|
# Docs:
|
|
5
|
-
# - https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/quickstart
|
|
6
|
-
# - https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/field-selection#guardrails--errors
|
|
5
|
+
# - https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/quickstart
|
|
6
|
+
# - https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/field-selection#guardrails--errors
|
|
7
7
|
class SearchEngine::<%= class_name %> < SearchEngine::Base
|
|
8
8
|
collection "<%= @collection_name %>"
|
|
9
9
|
<% Array(@attributes).each do |(name, type)| -%>
|
|
@@ -5,7 +5,7 @@ module SearchEngine
|
|
|
5
5
|
# Manage stopword sets for a collection.
|
|
6
6
|
#
|
|
7
7
|
# @since 0.1.0
|
|
8
|
-
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/synonyms-stopwords#management
|
|
8
|
+
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/synonyms-stopwords#management
|
|
9
9
|
# @see `https://typesense.org/docs/latest/api/stopwords.html`
|
|
10
10
|
module Stopwords
|
|
11
11
|
class << self
|
|
@@ -5,7 +5,7 @@ module SearchEngine
|
|
|
5
5
|
# Manage synonym sets for a collection.
|
|
6
6
|
#
|
|
7
7
|
# @since 0.1.0
|
|
8
|
-
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/synonyms-stopwords#management
|
|
8
|
+
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/synonyms-stopwords#management
|
|
9
9
|
# @see `https://typesense.org/docs/latest/api/synonyms.html`
|
|
10
10
|
module Synonyms
|
|
11
11
|
class << self
|
|
@@ -8,7 +8,7 @@ module SearchEngine
|
|
|
8
8
|
# #children and #each_child, and compact debug output.
|
|
9
9
|
# Subclasses must implement #type and override readers as needed.
|
|
10
10
|
#
|
|
11
|
-
# @see `https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/query-dsl`
|
|
11
|
+
# @see `https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/query-dsl`
|
|
12
12
|
class Node
|
|
13
13
|
# Maximum preview length for inspect payloads
|
|
14
14
|
INSPECT_PREVIEW_LIMIT = 80
|
data/lib/search_engine/ast.rb
CHANGED
|
@@ -23,7 +23,7 @@ module SearchEngine
|
|
|
23
23
|
#
|
|
24
24
|
# Exposes ergonomic builders as module functions, returning immutable nodes.
|
|
25
25
|
#
|
|
26
|
-
# @see `https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/query-dsl`
|
|
26
|
+
# @see `https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/query-dsl`
|
|
27
27
|
module AST
|
|
28
28
|
module_function
|
|
29
29
|
|
|
@@ -234,7 +234,7 @@ module SearchEngine
|
|
|
234
234
|
elsif !valid
|
|
235
235
|
raise SearchEngine::Errors::InvalidParams.new(
|
|
236
236
|
err,
|
|
237
|
-
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/indexer#troubleshooting',
|
|
237
|
+
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/indexer#troubleshooting',
|
|
238
238
|
details: { field: key.to_s, expected: expected, got: value.class.name }
|
|
239
239
|
)
|
|
240
240
|
end
|
|
@@ -338,7 +338,7 @@ module SearchEngine
|
|
|
338
338
|
msg = "Missing required fields: #{missing.to_a.sort.inspect} for #{klass.name}."
|
|
339
339
|
raise SearchEngine::Errors::InvalidParams.new(
|
|
340
340
|
msg,
|
|
341
|
-
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/indexer#troubleshooting',
|
|
341
|
+
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/indexer#troubleshooting',
|
|
342
342
|
details: { missing_required: missing.to_a.sort }
|
|
343
343
|
)
|
|
344
344
|
end
|
|
@@ -352,7 +352,7 @@ module SearchEngine
|
|
|
352
352
|
].join(' ')
|
|
353
353
|
raise SearchEngine::Errors::InvalidField.new(
|
|
354
354
|
msg,
|
|
355
|
-
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/indexer#troubleshooting',
|
|
355
|
+
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/indexer#troubleshooting',
|
|
356
356
|
details: { extras: extras.to_a.sort }
|
|
357
357
|
)
|
|
358
358
|
end
|
|
@@ -523,7 +523,7 @@ module SearchEngine
|
|
|
523
523
|
msg = "#{msg} (e.g., #{sample})" if sample
|
|
524
524
|
raise SearchEngine::Errors::InvalidParams.new(
|
|
525
525
|
msg,
|
|
526
|
-
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/indexer#troubleshooting',
|
|
526
|
+
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/indexer#troubleshooting',
|
|
527
527
|
details: result
|
|
528
528
|
)
|
|
529
529
|
end
|
|
@@ -12,9 +12,9 @@ module SearchEngine
|
|
|
12
12
|
# Supports FORMAT env var (table/json) and redaction-aware details.
|
|
13
13
|
#
|
|
14
14
|
# @since M8
|
|
15
|
-
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/cli#doctor
|
|
15
|
+
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/cli#doctor
|
|
16
16
|
module Doctor
|
|
17
|
-
DOCS_BASE = 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/'
|
|
17
|
+
DOCS_BASE = 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/'
|
|
18
18
|
|
|
19
19
|
module_function
|
|
20
20
|
|
|
@@ -30,7 +30,7 @@ module SearchEngine
|
|
|
30
30
|
# Returns exit code (0 success, 1 failure).
|
|
31
31
|
# @return [Integer]
|
|
32
32
|
# @since M8
|
|
33
|
-
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/cli#doctor
|
|
33
|
+
# @see https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/cli#doctor
|
|
34
34
|
def run
|
|
35
35
|
puts 'Executing doctor checks...'
|
|
36
36
|
|
|
@@ -136,7 +136,7 @@ module SearchEngine
|
|
|
136
136
|
ok = missing.empty?
|
|
137
137
|
hint = unless ok
|
|
138
138
|
'Set TYPESENSE_* envs or configure in an initializer. ' \
|
|
139
|
-
'See https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/installation#configuration'
|
|
139
|
+
'See https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/installation#configuration'
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
details = cfg.to_h_redacted
|
|
@@ -158,7 +158,7 @@ module SearchEngine
|
|
|
158
158
|
started,
|
|
159
159
|
error,
|
|
160
160
|
hint: 'Unexpected error reading configuration',
|
|
161
|
-
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/configuration'
|
|
161
|
+
doc: 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/configuration'
|
|
162
162
|
)
|
|
163
163
|
end
|
|
164
164
|
|
|
@@ -275,7 +275,7 @@ module SearchEngine
|
|
|
275
275
|
nil
|
|
276
276
|
else
|
|
277
277
|
'Run schema lifecycle to create physical collections and swap alias. ' \
|
|
278
|
-
'See https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/schema#lifecycle'
|
|
278
|
+
'See https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/schema#lifecycle'
|
|
279
279
|
end
|
|
280
280
|
details = { resolved: resolved, missing: missing }
|
|
281
281
|
Builder.result_for_check(
|
|
@@ -56,7 +56,7 @@ module SearchEngine
|
|
|
56
56
|
|
|
57
57
|
# Fallback: attempt a generic call via low-level typesense endpoint access if available.
|
|
58
58
|
# This keeps adapter permissive for future endpoints without adding Faraday here.
|
|
59
|
-
raise ArgumentError, "Unsupported request path for adapter: #{request.
|
|
59
|
+
raise ArgumentError, "Unsupported request path for adapter: #{request.http_method} #{request.path}"
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
end
|
|
@@ -10,7 +10,7 @@ module SearchEngine
|
|
|
10
10
|
# Sanitizes internal-only keys before encoding to ensure the payload is
|
|
11
11
|
# compatible with the Typesense API.
|
|
12
12
|
#
|
|
13
|
-
# @see `https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/client`
|
|
13
|
+
# @see `https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/client`
|
|
14
14
|
# @see `https://typesense.org/docs/latest/api/`
|
|
15
15
|
class RequestBuilder
|
|
16
16
|
# Normalized request container used by the transport adapter.
|
|
@@ -39,7 +39,7 @@ module SearchEngine
|
|
|
39
39
|
DEFAULT_HEADERS_JSON = { 'Content-Type' => CONTENT_TYPE_JSON }.freeze
|
|
40
40
|
|
|
41
41
|
# Centralized doc links used by client error mapping
|
|
42
|
-
DOC_CLIENT_ERRORS = 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/client#errors'
|
|
42
|
+
DOC_CLIENT_ERRORS = 'https://nikita-shkoda.mintlify.app/projects/search-engine-for-typesense/v30.1/client#errors'
|
|
43
43
|
|
|
44
44
|
INTERNAL_ONLY_KEYS = %i[
|
|
45
45
|
_join
|
|
@@ -41,8 +41,8 @@ module SearchEngine
|
|
|
41
41
|
client.__send__(:with_exception_mapping, *args, &block)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
def instrument(*args)
|
|
45
|
-
client.__send__(:instrument, *args)
|
|
44
|
+
def instrument(*args, **kwargs)
|
|
45
|
+
client.__send__(:instrument, *args, **kwargs)
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def log_success(*args)
|
|
@@ -28,7 +28,7 @@ module SearchEngine
|
|
|
28
28
|
|
|
29
29
|
raise
|
|
30
30
|
ensure
|
|
31
|
-
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
31
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
# @param collection_name [String]
|
|
@@ -54,7 +54,7 @@ module SearchEngine
|
|
|
54
54
|
|
|
55
55
|
raise
|
|
56
56
|
ensure
|
|
57
|
-
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
57
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
# @param alias_name [String]
|
|
@@ -72,7 +72,7 @@ module SearchEngine
|
|
|
72
72
|
|
|
73
73
|
symbolize_keys_deep(result)
|
|
74
74
|
ensure
|
|
75
|
-
instrument(:put, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
75
|
+
instrument(:put, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# @param schema [Hash]
|
|
@@ -88,7 +88,7 @@ module SearchEngine
|
|
|
88
88
|
|
|
89
89
|
symbolize_keys_deep(result)
|
|
90
90
|
ensure
|
|
91
|
-
instrument(:post, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
91
|
+
instrument(:post, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
# @param name [String]
|
|
@@ -106,7 +106,7 @@ module SearchEngine
|
|
|
106
106
|
|
|
107
107
|
symbolize_keys_deep(result)
|
|
108
108
|
ensure
|
|
109
|
-
instrument(:patch, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
109
|
+
instrument(:patch, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
# @param name [String]
|
|
@@ -133,7 +133,7 @@ module SearchEngine
|
|
|
133
133
|
|
|
134
134
|
raise
|
|
135
135
|
ensure
|
|
136
|
-
instrument(:delete, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
136
|
+
instrument(:delete, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
139
|
# @return [Array<Hash>]
|
|
@@ -153,7 +153,7 @@ module SearchEngine
|
|
|
153
153
|
|
|
154
154
|
symbolize_keys_deep(result)
|
|
155
155
|
ensure
|
|
156
|
-
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
156
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
157
157
|
end
|
|
158
158
|
end
|
|
159
159
|
end
|
|
@@ -23,7 +23,7 @@ module SearchEngine
|
|
|
23
23
|
ts.collections[collection].documents.import(jsonl, action: action.to_s)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
instrument(:post, path, current_monotonic_ms - start, {})
|
|
26
|
+
instrument(:post, path, current_monotonic_ms - start, {}, request_token: start)
|
|
27
27
|
result
|
|
28
28
|
end
|
|
29
29
|
|
|
@@ -51,7 +51,7 @@ module SearchEngine
|
|
|
51
51
|
ts.collections[collection].documents.delete(filter_by: filter_by)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
instrument(:delete, path, current_monotonic_ms - start, {})
|
|
54
|
+
instrument(:delete, path, current_monotonic_ms - start, {}, request_token: start)
|
|
55
55
|
symbolize_keys_deep(result)
|
|
56
56
|
end
|
|
57
57
|
|
|
@@ -84,7 +84,7 @@ module SearchEngine
|
|
|
84
84
|
|
|
85
85
|
raise
|
|
86
86
|
ensure
|
|
87
|
-
instrument(:delete, path, current_monotonic_ms - start, {}) if defined?(start)
|
|
87
|
+
instrument(:delete, path, current_monotonic_ms - start, {}, request_token: start) if defined?(start)
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
# @param collection [String]
|
|
@@ -112,7 +112,7 @@ module SearchEngine
|
|
|
112
112
|
result = with_exception_mapping(:patch, path, {}, start) do
|
|
113
113
|
ts.collections[collection].documents[s].update(fields)
|
|
114
114
|
end
|
|
115
|
-
instrument(:patch, path, current_monotonic_ms - start, {})
|
|
115
|
+
instrument(:patch, path, current_monotonic_ms - start, {}, request_token: start)
|
|
116
116
|
symbolize_keys_deep(result)
|
|
117
117
|
end
|
|
118
118
|
|
|
@@ -142,7 +142,7 @@ module SearchEngine
|
|
|
142
142
|
ts.collections[collection].documents.update(fields, filter_by: filter_by)
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
instrument(:patch, path, current_monotonic_ms - start, {})
|
|
145
|
+
instrument(:patch, path, current_monotonic_ms - start, {}, request_token: start)
|
|
146
146
|
symbolize_keys_deep(result)
|
|
147
147
|
end
|
|
148
148
|
|
|
@@ -162,7 +162,7 @@ module SearchEngine
|
|
|
162
162
|
typesense.collections[collection].documents.create(document)
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
instrument(:post, path, current_monotonic_ms - start, {})
|
|
165
|
+
instrument(:post, path, current_monotonic_ms - start, {}, request_token: start)
|
|
166
166
|
symbolize_keys_deep(result)
|
|
167
167
|
end
|
|
168
168
|
|
|
@@ -196,7 +196,11 @@ module SearchEngine
|
|
|
196
196
|
|
|
197
197
|
raise
|
|
198
198
|
ensure
|
|
199
|
-
|
|
199
|
+
if defined?(start)
|
|
200
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {},
|
|
201
|
+
request_token: start
|
|
202
|
+
)
|
|
203
|
+
end
|
|
200
204
|
end
|
|
201
205
|
|
|
202
206
|
private
|
|
@@ -15,7 +15,7 @@ module SearchEngine
|
|
|
15
15
|
|
|
16
16
|
symbolize_keys_deep(result)
|
|
17
17
|
ensure
|
|
18
|
-
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
18
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def list_api_keys
|
|
@@ -37,7 +37,7 @@ module SearchEngine
|
|
|
37
37
|
|
|
38
38
|
symbolize_keys_deep(result)
|
|
39
39
|
ensure
|
|
40
|
-
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
40
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def clear_cache
|
|
@@ -48,7 +48,7 @@ module SearchEngine
|
|
|
48
48
|
typesense.operations.perform('cache/clear')
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
instrument(:post, path, current_monotonic_ms - start, {})
|
|
51
|
+
instrument(:post, path, current_monotonic_ms - start, {}, request_token: start)
|
|
52
52
|
symbolize_keys_deep(result)
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -75,7 +75,7 @@ module SearchEngine
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
ensure
|
|
78
|
-
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
78
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
# Return raw server statistics from Typesense.
|
|
@@ -101,7 +101,7 @@ module SearchEngine
|
|
|
101
101
|
end
|
|
102
102
|
end
|
|
103
103
|
ensure
|
|
104
|
-
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {})
|
|
104
|
+
instrument(:get, path, (start ? (current_monotonic_ms - start) : 0.0), {}, request_token: start)
|
|
105
105
|
end
|
|
106
106
|
|
|
107
107
|
private
|
|
@@ -21,7 +21,7 @@ module SearchEngine
|
|
|
21
21
|
|
|
22
22
|
result = instrumented_search(collection, params_obj, cache_params, path, payload, start)
|
|
23
23
|
duration = current_monotonic_ms - start
|
|
24
|
-
instrument(:post, path, duration, cache_params)
|
|
24
|
+
instrument(:post, path, duration, cache_params, request_token: start)
|
|
25
25
|
log_success(:post, path, start, cache_params)
|
|
26
26
|
|
|
27
27
|
klass = begin
|
|
@@ -48,7 +48,7 @@ module SearchEngine
|
|
|
48
48
|
typesense.multi_search.perform({ searches: bodies }, common_params: cache_params)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
instrument(:post, path, current_monotonic_ms - start, cache_params)
|
|
51
|
+
instrument(:post, path, current_monotonic_ms - start, cache_params, request_token: start)
|
|
52
52
|
symbolize_keys_deep(result)
|
|
53
53
|
end
|
|
54
54
|
|
|
@@ -129,7 +129,7 @@ module SearchEngine
|
|
|
129
129
|
|
|
130
130
|
pinned = params[:pinned_hits]
|
|
131
131
|
hidden = params[:hidden_hits]
|
|
132
|
-
tags = params[:override_tags]
|
|
132
|
+
tags = params[:curation_tags] || params[:override_tags]
|
|
133
133
|
|
|
134
134
|
pinned_count =
|
|
135
135
|
case pinned
|