redi_search 4.1.0 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/lint.yml +3 -3
  3. data/.github/workflows/tests.yml +9 -6
  4. data/.rubocop.yml +1 -5
  5. data/Appraisals +4 -0
  6. data/Gemfile +2 -1
  7. data/README.md +57 -61
  8. data/bin/console +8 -4
  9. data/bin/publish +2 -2
  10. data/gemfiles/activerecord_60.gemfile +1 -0
  11. data/gemfiles/activerecord_61.gemfile +1 -0
  12. data/gemfiles/activerecord_70.gemfile +16 -0
  13. data/lib/redi_search/add_field.rb +9 -15
  14. data/lib/redi_search/client.rb +10 -8
  15. data/lib/redi_search/document/display.rb +4 -4
  16. data/lib/redi_search/document.rb +7 -12
  17. data/lib/redi_search/index.rb +4 -11
  18. data/lib/redi_search/lazily_load.rb +3 -3
  19. data/lib/redi_search/log_subscriber.rb +6 -2
  20. data/lib/redi_search/model.rb +20 -28
  21. data/lib/redi_search/schema/field.rb +17 -3
  22. data/lib/redi_search/schema/geo_field.rb +5 -6
  23. data/lib/redi_search/schema/numeric_field.rb +13 -6
  24. data/lib/redi_search/schema/tag_field.rb +12 -8
  25. data/lib/redi_search/schema/text_field.rb +7 -6
  26. data/lib/redi_search/schema.rb +33 -25
  27. data/lib/redi_search/search/clauses/and.rb +0 -2
  28. data/lib/redi_search/search/clauses/application_clause.rb +0 -2
  29. data/lib/redi_search/search/clauses/boolean.rb +1 -1
  30. data/lib/redi_search/search/clauses/in_order.rb +0 -2
  31. data/lib/redi_search/search/clauses/language.rb +0 -2
  32. data/lib/redi_search/search/clauses/limit.rb +0 -2
  33. data/lib/redi_search/search/clauses/no_content.rb +0 -2
  34. data/lib/redi_search/search/clauses/no_stop_words.rb +0 -2
  35. data/lib/redi_search/search/clauses/or.rb +0 -2
  36. data/lib/redi_search/search/clauses/return.rb +0 -2
  37. data/lib/redi_search/search/clauses/slop.rb +0 -2
  38. data/lib/redi_search/search/clauses/sort_by.rb +0 -2
  39. data/lib/redi_search/search/clauses/verbatim.rb +0 -2
  40. data/lib/redi_search/search/clauses/where.rb +1 -1
  41. data/lib/redi_search/search/clauses/with_scores.rb +0 -2
  42. data/lib/redi_search/search/clauses.rb +0 -16
  43. data/lib/redi_search/search/result.rb +13 -3
  44. data/lib/redi_search/search/term.rb +16 -13
  45. data/lib/redi_search/search.rb +1 -7
  46. data/lib/redi_search/spellcheck/result.rb +4 -4
  47. data/lib/redi_search/spellcheck.rb +4 -8
  48. data/lib/redi_search/validatable.rb +0 -4
  49. data/lib/redi_search/validations/numericality.rb +0 -2
  50. data/lib/redi_search/version.rb +1 -1
  51. data/lib/redi_search.rb +4 -8
  52. data/redi_search.gemspec +10 -7
  53. metadata +22 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ae66b8370802c6acf6c50487cc751e526bd7afa69be14bf56e0e5b8db416511
4
- data.tar.gz: ccffbbb3db86598eb132225091cf3cfae3bfac692bca430d2484e7c97f0ab81c
3
+ metadata.gz: 7bb651cd81b7d83eb69c31a88bc6680c47083c324bd0a7e2670081fa479b12fa
4
+ data.tar.gz: '037638518a882a238acf3f81c08e2598733ecfc3b8571a9e93e37c894f8b73aa'
5
5
  SHA512:
6
- metadata.gz: 037fd2b21e9e296e3b143f4d878a9e9cb37406f99c66b22f54a218d1a3d12c046034b19d011b875b2cd5ab3d9a1bb81c4f10b4c862196d01e8a408a2d6436156
7
- data.tar.gz: 17e0f4dccd59d130c3d76314cff4b2a94da725b1b5bdc2478aaf39dde5c3a34d178cbafb04db45bf5488a8a7006bb043ed14247e46a47a64d362cc94b6fe52f1
6
+ metadata.gz: 3c3ddf47605dee892bdf811d2bcab81ce503431532ae481e1c1a49f611061c5b43a01d2d45325901c658e14a4ceb706b743411439f14bd235ed44fddecaf6716
7
+ data.tar.gz: 1879a477cae2f84072f28d20d88ce4d6e61b1b28ea4e2966cec01ebc14e9fed61b45b43a3688eacb0979f31647b5c66ff55c460f852a68b8154348effd0c8ee0
@@ -4,17 +4,17 @@ on:
4
4
  pull_request:
5
5
  push:
6
6
  branches:
7
- - master
7
+ - main
8
8
 
9
9
  jobs:
10
10
  lint:
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - uses: actions/checkout@v2
14
- - name: Set up Ruby 3.0
14
+ - name: Set up Ruby 3.1
15
15
  uses: ruby/setup-ruby@v1
16
16
  with:
17
- ruby-version: 3.0
17
+ ruby-version: 3.1
18
18
  - name: Install rubocop
19
19
  run: |
20
20
  gem install rubocop rubocop-performance rubocop-minitest rubocop-rake
@@ -4,15 +4,15 @@ on:
4
4
  pull_request:
5
5
  push:
6
6
  branches:
7
- - master
7
+ - main
8
8
 
9
9
  jobs:
10
10
  unit:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- ruby: [ '2.5', '2.6', '2.7', '3.0' ]
15
- gemfile: [ 'Gemfile', 'gemfiles/activerecord_60.gemfile' ]
14
+ ruby: [ '2.7', '3.0', '3.1' ]
15
+ gemfile: [ 'Gemfile', 'gemfiles/activerecord_60.gemfile', 'gemfiles/activerecord_61.gemfile', 'gemfiles/activerecord_70.gemfile' ]
16
16
  steps:
17
17
  - uses: actions/checkout@v2
18
18
  - name: Set up Ruby ${{ matrix.ruby }}
@@ -29,17 +29,20 @@ jobs:
29
29
  run: BUNDLE_GEMFILE=${{ matrix.gemfile }} bundle exec rake test:unit
30
30
  integration:
31
31
  runs-on: ubuntu-latest
32
+ strategy:
33
+ matrix:
34
+ redisearch: [ '2.4.7' ]
32
35
  services:
33
36
  redisearch:
34
- image: redislabs/redisearch:2.0.6
37
+ image: redislabs/redisearch:${{ matrix.redisearch }}
35
38
  ports:
36
39
  - 6379:6379
37
40
  steps:
38
41
  - uses: actions/checkout@v2
39
- - name: Set up Ruby 3.0
42
+ - name: Set up Ruby 3.1
40
43
  uses: ruby/setup-ruby@v1
41
44
  with:
42
- ruby-version: 3.0
45
+ ruby-version: 3.1
43
46
  - name: Install dependencies
44
47
  run: |
45
48
  sudo apt-get install libsqlite3-dev -y
data/.rubocop.yml CHANGED
@@ -13,7 +13,7 @@ AllCops:
13
13
  - test/dummy/db/schema.rb
14
14
  - gemfiles/**/*
15
15
  - bin/**/*
16
- TargetRubyVersion: 2.5
16
+ TargetRubyVersion: 2.7
17
17
 
18
18
  # Department Bundler
19
19
  Bundler/DuplicatedGem:
@@ -619,10 +619,6 @@ Lint/BinaryOperatorWithIdenticalOperands:
619
619
  Description: Checks for comparison of something with itself.
620
620
  Enabled: true
621
621
 
622
- Lint/UselessElseWithoutRescue:
623
- Description: Checks for useless `else` in `begin..end` without `rescue`.
624
- Enabled: true
625
-
626
622
  Lint/ReturnInVoidContext:
627
623
  Description: Checks for return in void context.
628
624
  Enabled: true
data/Appraisals CHANGED
@@ -7,3 +7,7 @@ end
7
7
  appraise "activerecord-61" do
8
8
  gem "activerecord", "< 6.2", ">= 6.1"
9
9
  end
10
+
11
+ appraise "activerecord-70" do
12
+ gem "activerecord", "~> 7.0.0.alpha1"
13
+ end
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
7
7
  gemspec
8
8
 
9
9
  gem "appraisal", "~> 2.2"
10
+ gem "debug"
10
11
  gem "faker"
11
12
  gem "mocha"
12
13
  gem "rubocop"
@@ -16,4 +17,4 @@ gem "rubocop-rake"
16
17
  gem "simplecov"
17
18
  gem "sqlite3"
18
19
 
19
- gem "activerecord", "~> 6.1"
20
+ gem "activerecord", "~> 7.0"
data/README.md CHANGED
@@ -1,14 +1,11 @@
1
1
  <p align="center">
2
2
  <a href="https://github.com/npezza93/redi_search">
3
- <img src="https://raw.githubusercontent.com/npezza93/redi_search/master/.github/logo.svg?sanitize=true" width="350">
3
+ <img src="https://raw.githubusercontent.com/npezza93/redi_search/main/.github/logo.svg?sanitize=true" width="350">
4
4
  </a>
5
5
  </p>
6
6
 
7
7
  # RediSearch
8
8
 
9
- ![Build Status](https://github.com/npezza93/redi_search/workflows/tests/badge.svg)
10
- [![Maintainability](https://api.codeclimate.com/v1/badges/c6437acac5684de2549d/maintainability)](https://codeclimate.com/github/npezza93/redi_search/maintainability)
11
-
12
9
  A simple, but powerful, Ruby wrapper around RediSearch, a search engine on top of
13
10
  Redis.
14
11
 
@@ -103,17 +100,19 @@ defining what a search index is. According to [Swiftype](https://swiftype.com):
103
100
  ## Schema
104
101
 
105
102
  This defines the fields and the properties of those fields in the index. A
106
- schema is a hash, with field names as the keys, and the field type(and options)
107
- as the value. Each field can be one of four types: geo, numeric, tag, or text
108
- and can have many options. A simple example of a schema is:
103
+ schema is a simple DSL. Each field can be one of four types: geo, numeric, tag,
104
+ or text and can have many options. A simple example of a schema is:
109
105
  ```ruby
110
- { first_name: :text, last_name: :text }
106
+ RediSearch::Schema.new do
107
+ text_field :first_name
108
+ text_field :last_name
109
+ end
111
110
  ```
112
111
 
113
112
  The supported options for each type are as follows:
114
113
 
115
114
  ##### Text field
116
- With no options: `{ name: :text }`
115
+ With no options: `text_field :name`
117
116
 
118
117
  <details>
119
118
  <summary>Options</summary>
@@ -122,7 +121,7 @@ With no options: `{ name: :text }`
122
121
  <b>weight</b> (default: 1.0)
123
122
  <ul>
124
123
  <li>Declares the importance of this field when calculating result accuracy. This is a multiplication factor.</li>
125
- <li>Ex: <code>{ name: { text: { weight: 2 } } }</code></li>
124
+ <li>Ex: <code>text_field :name, weight: 2</code></li>
126
125
  </ul>
127
126
  </li>
128
127
  <li>
@@ -137,7 +136,7 @@ With no options: `{ name: :text }`
137
136
  </ul>
138
137
  </li>
139
138
  <li>
140
- Ex: <code>{ name: { text: { phonetic: 'dm:en' } } }</code>
139
+ Ex: <code>text_field :name, phonetic: 'dm:en'</code>
141
140
  </li>
142
141
  </ul>
143
142
  </li>
@@ -145,28 +144,28 @@ With no options: `{ name: :text }`
145
144
  <b>sortable</b> (default: false)
146
145
  <ul>
147
146
  <li>Allows the user to later sort the results by the value of this field (this adds memory overhead so do not declare it on large text fields).</li>
148
- <li>Ex: <code>{ name: { text: { sortable: true } } }</code></li>
147
+ <li>Ex: <code>text_field :name, sortable: true</code></li>
149
148
  </ul>
150
149
  </li>
151
150
  <li>
152
151
  <b>no_index</b> (default: false)
153
152
  <ul>
154
153
  <li>Field will not be indexed. This is useful in conjunction with <code>sortable</code>, to create fields whose update using PARTIAL will not cause full reindexing of the document. If a field has <code>no_index</code> and doesn't have <code>sortable</code>, it will just be ignored by the index.</li>
155
- <li>Ex: <code>{ name: { text: { no_index: true } } }</code></li>
154
+ <li>Ex: <code>text_field :name, no_index: true</code></li>
156
155
  </ul>
157
156
  </li>
158
157
  <li>
159
158
  <b>no_stem</b> (default: false)
160
159
  <ul>
161
160
  <li>Disable stemming when indexing its values. This may be ideal for things like proper names.</li>
162
- <li>Ex: <code>{ name: { text: { no_stem: true } } }</code></li>
161
+ <li>Ex: <code>text_feidl :name, no_stem: true</code></li>
163
162
  </ul>
164
163
  </li>
165
164
  </ul>
166
165
  </details>
167
166
 
168
167
  ##### Numeric field
169
- With no options: `{ price: :numeric }`
168
+ With no options: `numeric_field :price`
170
169
 
171
170
  <details>
172
171
  <summary>Options</summary>
@@ -175,21 +174,21 @@ With no options: `{ price: :numeric }`
175
174
  <b>sortable</b> (default: false)
176
175
  <ul>
177
176
  <li>Allows the user to later sort the results by the value of this field (this adds memory overhead so do not declare it on large text fields).</li>
178
- <li>Ex: <code>{ id: { numeric: { sortable: true } } }</code></li>
177
+ <li>Ex: <code>numeric_field :id, sortable: true</code></li>
179
178
  </ul>
180
179
  </li>
181
180
  <li>
182
181
  <b>no_index</b> (default: false)
183
182
  <ul>
184
183
  <li>Field will not be indexed. This is useful in conjunction with <code>sortable</code>, to create fields whose update using PARTIAL will not cause full reindexing of the document. If a field has <code>no_index</code> and doesn't have <code>sortable</code>, it will just be ignored by the index.</li>
185
- <li>Ex: <code>{ id: { numeric: { no_index: true } } }</code></li>
184
+ <li>Ex: <code>numeric_field :id, no_index: true</code></li>
186
185
  </ul>
187
186
  </li>
188
187
  </ul>
189
188
  </details>
190
189
 
191
190
  ##### Tag field
192
- With no options: `{ tag: :tag }`
191
+ With no options: `tag_field :tag`
193
192
 
194
193
  <details>
195
194
  <summary>Options</summary>
@@ -198,28 +197,28 @@ With no options: `{ tag: :tag }`
198
197
  <b>sortable</b> (default: false)
199
198
  <ul>
200
199
  <li>Allows the user to later sort the results by the value of this field (this adds memory overhead so do not declare it on large text fields).</li>
201
- <li>Ex: <code>{ tag: { tag: { sortable: true } } }</code></li>
200
+ <li>Ex: <code>tag_field :tag, sortable: true</code></li>
202
201
  </ul>
203
202
  </li>
204
203
  <li>
205
204
  <b>no_index</b> (default: false)
206
205
  <ul>
207
206
  <li>Field will not be indexed. This is useful in conjunction with <code>sortable</code>, to create fields whose update using PARTIAL will not cause full reindexing of the document. If a field has <code>no_index</code> and doesn't have <code>sortable</code>, it will just be ignored by the index.</li>
208
- <li>Ex: <code>{ tag: { tag: { no_index: true } } }</code></li>
207
+ <li>Ex: <code>tag_field :tag, no_index: true</code></li>
209
208
  </ul>
210
209
  </li>
211
210
  <li>
212
211
  <b>separator</b> (default: ",")
213
212
  <ul>
214
213
  <li>Indicates how the text contained in the field is to be split into individual tags. The default is ,. The value must be a single character.</li>
215
- <li>Ex: <code>{ tag: { tag: { separator: ',' } } }</code></li>
214
+ <li>Ex: <code>tag_field :tag, separator: ','</code></li>
216
215
  </ul>
217
216
  </li>
218
217
  </ul>
219
218
  </details>
220
219
 
221
220
  ##### Geo field
222
- With no options: `{ place: :geo }`
221
+ With no options: `geo_field :place`
223
222
 
224
223
  <details>
225
224
  <summary>Options</summary>
@@ -228,14 +227,14 @@ With no options: `{ place: :geo }`
228
227
  <b>sortable</b> (default: false)
229
228
  <ul>
230
229
  <li>Allows the user to later sort the results by the value of this field (this adds memory overhead so do not declare it on large text fields).</li>
231
- <li>Ex: <code>{ place: { geo: { sortable: true } } }</code></li>
230
+ <li>Ex: <code>geo_field :place, sortable: true</code></li>
232
231
  </ul>
233
232
  </li>
234
233
  <li>
235
234
  <b>no_index</b> (default: false)
236
235
  <ul>
237
236
  <li>Field will not be indexed. This is useful in conjunction with <code>sortable</code>, to create fields whose update using PARTIAL will not cause full reindexing of the document. If a field has <code>no_index</code> and doesn't have <code>sortable</code>, it will just be ignored by the index.</li>
238
- <li>Ex: <code>{ place: { geo: { no_index: true } } }</code></li>
237
+ <li>Ex: <code>geo_field :place, no_index: true</code></li>
239
238
  </ul>
240
239
  </li>
241
240
  </ul>
@@ -250,12 +249,10 @@ You can fetch a `Document` using `.get` class methods.
250
249
  given `document_id`.
251
250
 
252
251
  You can also make a `Document` instance using the
253
- `.for_object(index, record, serializer: nil, only: [])` class method. It takes
252
+ `.for_object(index, record, only: [])` class method. It takes
254
253
  an `Index` instance and a Ruby object. That object must respond to all the
255
- fields specified in the `Index`'s `Schema` or pass a serializer class that
256
- accepts the object and responds to all the fields specified in the `Index`'s
257
- `Schema`. `only` accepts an array of fields from the schema and limits the
258
- fields that are passed to the `Document`.
254
+ fields specified in the `Index`'s `Schema`. `only` accepts an array of fields
255
+ from the schema and limits the fields that are passed to the `Document`.
259
256
 
260
257
  Once you have an instance of a `Document`, it responds to all the fields
261
258
  specified in the `Index`'s `Schema` as methods and `document_id`. `document_id`
@@ -271,10 +268,12 @@ Finally there is a `#del` method that will remove the `Document` from the
271
268
  ## Index
272
269
 
273
270
  To initialize an `Index`, pass the name of the `Index` as a string or symbol
274
- and the `Schema`.
271
+ and the `Schema` block.
275
272
 
276
273
  ```ruby
277
- RediSearch::Index.new(name_of_index, schema)
274
+ RediSearch::Index.new(name_of_index) do
275
+ text_field :foobar
276
+ end
278
277
  ```
279
278
 
280
279
  #### Available Commands
@@ -330,8 +329,10 @@ RediSearch::Index.new(name_of_index, schema)
330
329
  - Removes a `Document` from the `Index`.
331
330
  - `document_count`
332
331
  - Returns the number of `Document`s in the `Index`
333
- - `add_field(field_name, schema)`
334
- - Adds a new field to the `Index`. Ex: `index.add_field(:first_name, text: { phonetic: "dm:en" })`
332
+ - `add_field(name, type, **options, &block)`
333
+ - Adds a new field to the `Index`.
334
+ - The block and options are optional.
335
+ - Ex: `index.add_field(:first_name, :text, phonetic: "dm:en")`
335
336
  - `reindex(documents, recreate: false)`
336
337
  - If `recreate` is `true` the `Index` will be dropped and recreated
337
338
 
@@ -343,7 +344,7 @@ be chained together. When searching, an array of `Document`s is returned
343
344
  which has public reader methods for all the schema fields.
344
345
 
345
346
  ```ruby
346
- main ❯ index = RediSearch::Index.new("user_idx", name: { text: { phonetic: "dm:en" } })
347
+ main ❯ index = RediSearch::Index.new("user_idx") { text_field :name, phonetic: "dm:en" }
347
348
  main ❯ index.add RediSearch::Document.for_object(index, User.new("10039", "Gene", "Volkman"))
348
349
  main ❯ index.add RediSearch::Document.for_object(index, User.new("9998", "Jeannie", "Ledner"))
349
350
  main ❯ index.search("john")
@@ -473,7 +474,7 @@ returns an array where each element contains suggestions for each search term
473
474
  and a normalized score based on its occurrences in the index.
474
475
 
475
476
  ```ruby
476
- main ❯ index = RediSearch::Index.new("user_idx", name: { text: { phonetic: "dm:en" } })
477
+ main ❯ index = RediSearch::Index.new("user_idx") { text_field :name, phonetic: "dm:en" }
477
478
  main ❯ index.spellcheck("jimy")
478
479
  RediSearch (1.1ms) FT.SPELLCHECK user_idx jimy DISTANCE 1
479
480
  => [#<RediSearch::Spellcheck::Result:0x00007f805591c670
@@ -495,10 +496,10 @@ keyword argument from inside your model. Ex:
495
496
 
496
497
  ```ruby
497
498
  class User < ApplicationRecord
498
- redi_search schema: {
499
- first: { text: { phonetic: "dm:en" } },
500
- last: { text: { phonetic: "dm:en" } }
501
- }
499
+ redi_search do
500
+ text_field :first, phonetic: "dm:en"
501
+ text_field :last, phonetic: "dm:en"
502
+ end
502
503
  end
503
504
  ```
504
505
 
@@ -515,21 +516,16 @@ similarly to `RediSearch::Index#reindex`. Some of the differences include:
515
516
  particular field.
516
517
 
517
518
 
518
- The `redi_search` class method also takes an optional `serializer` argument
519
- which takes the class name of a serializer. The serializer must respond to all
520
- the fields in a schema as methods. We don't serialize to a JSON object since
521
- RediSearch doesn't serialize documents that way.
519
+ While defining the schema you can optionally pass it a block. If no block is
520
+ passed the `name` will called on the model to get the value. If a block is
521
+ passed the value for the field is obtained through calling the block.
522
522
 
523
523
  ```ruby
524
524
  class User < ApplicationRecord
525
- redi_search schema: {
526
- name: { text: { phonetic: "dm:en" } }
527
- }, serializer: UserSerializer
528
- end
529
-
530
- class UserSerializer < SimpleDelegator
531
- def name
532
- "#{first_name} #{last_name}"
525
+ redi_search do
526
+ text_field :name do
527
+ "#{first_name} #{last_name}"
528
+ end
533
529
  end
534
530
  end
535
531
  ```
@@ -553,13 +549,13 @@ optional `index_prefix` argument which gets prepended to the index name:
553
549
 
554
550
  ```ruby
555
551
  class User < ApplicationRecord
556
- redi_search schema: {
557
- first: { text: { phonetic: "dm:en" } },
558
- last: { text: { phonetic: "dm:en" } }
559
- }, index_prefix: 'prefix'
552
+ redi_search index_prefix: 'prefix' do
553
+ text_field :first, phonetic: "dm:en"
554
+ text_field :last, phonetic: "dm:en"
555
+ end
560
556
  end
561
557
 
562
- User.redi_search_index.name
558
+ User.search_index.name
563
559
  # => prefix_users_development
564
560
  ```
565
561
 
@@ -568,13 +564,13 @@ after creating and updating and will be removed from the `Index` upon
568
564
  destruction.
569
565
 
570
566
  There are a few more convenience methods that are publicly available:
571
- - `redi_search_document`
567
+ - `search_document`
572
568
  - Returns the record as a `RediSearch::Document` instance
573
- - `redi_search_delete_document`
569
+ - `remove_from_index`
574
570
  - Removes the record from the `Index`
575
- - `redi_search_add_document`
571
+ - `add_to_index`
576
572
  - Adds the record to the `Index`
577
- - `redi_search_index`
573
+ - `search_index`
578
574
  - Returns the `RediSearch::Index` instance
579
575
 
580
576
 
@@ -608,4 +604,4 @@ The gem is available as open source under the terms of the
608
604
 
609
605
  Everyone interacting in the RediSearch project’s codebases, issue trackers, chat
610
606
  rooms and mailing lists is expected to follow the [code of
611
- conduct](https://github.com/npezza93/redi_search/blob/master/CODE_OF_CONDUCT.md).
607
+ conduct](https://github.com/npezza93/redi_search/blob/main/CODE_OF_CONDUCT.md).
data/bin/console CHANGED
@@ -19,10 +19,14 @@ ActiveRecord::Migration.create_table :users do |t|
19
19
  end
20
20
 
21
21
  class User < ActiveRecord::Base
22
- redi_search schema: {
23
- first: { text: { phonetic: "dm:en" } },
24
- last: { text: { phonetic: "dm:en" } }
25
- }
22
+ redi_search do
23
+ text_field :first, phonetic: "dm:en"
24
+ text_field :last, phonetic: "dm:en"
25
+ tag_field :tags
26
+ text_field :name, phonetic: "dm:en" do
27
+ "#{first} #{last}"
28
+ end
29
+ end
26
30
  end
27
31
 
28
32
  def seed_users(count = 10_000)
data/bin/publish CHANGED
@@ -8,7 +8,7 @@ require_relative "../lib/redi_search/version"
8
8
  # path to your application root.
9
9
  APP_ROOT = Pathname.new File.expand_path("..", __dir__)
10
10
  MASTER_CHECK = <<~MASTER_CHECK
11
- if [ $(git symbolic-ref --short -q HEAD) != 'master' ];
11
+ if [ $(git symbolic-ref --short -q HEAD) != 'main' ];
12
12
  then exit 1;
13
13
  fi
14
14
  MASTER_CHECK
@@ -20,7 +20,7 @@ end
20
20
 
21
21
  abort("\n== Version Type incorrect ==") unless VERSION_TYPES.include?(ARGV[0])
22
22
 
23
- abort("\n== Not on master") unless system(MASTER_CHECK)
23
+ abort("\n== Not on main") unless system(MASTER_CHECK)
24
24
 
25
25
  current_version = RediSearch::VERSION.split(".").map(&:to_i)
26
26
 
@@ -3,6 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal", "~> 2.2"
6
+ gem "debug"
6
7
  gem "faker"
7
8
  gem "mocha"
8
9
  gem "rubocop"
@@ -3,6 +3,7 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gem "appraisal", "~> 2.2"
6
+ gem "debug"
6
7
  gem "faker"
7
8
  gem "mocha"
8
9
  gem "rubocop"
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.2"
6
+ gem "debug"
7
+ gem "faker"
8
+ gem "mocha"
9
+ gem "rubocop"
10
+ gem "rubocop-minitest"
11
+ gem "rubocop-performance"
12
+ gem "simplecov"
13
+ gem "sqlite3"
14
+ gem "activerecord", "~> 7.0.1"
15
+
16
+ gemspec path: "../"
@@ -2,16 +2,18 @@
2
2
 
3
3
  module RediSearch
4
4
  class AddField
5
- def initialize(index, field_name, schema)
6
- @index = index
7
- @field_name = field_name
8
- @raw_schema = schema
5
+ def initialize(index, name, type, **options, &block)
6
+ @index = index
7
+ @name = name
8
+ @type = type
9
+ @options = options
10
+ @block = block
9
11
  end
10
12
 
11
13
  def call!
12
- index.schema.add_field(field_name, raw_schema)
14
+ field = index.schema.add_field(name, type, **options, &block)
13
15
 
14
- RediSearch.client.call!(*command).ok?
16
+ RediSearch.client.call!("ALTER", index.name, "SCHEMA", "ADD", *field).ok?
15
17
  end
16
18
 
17
19
  def call
@@ -22,14 +24,6 @@ module RediSearch
22
24
 
23
25
  private
24
26
 
25
- attr_reader :index, :field_name, :raw_schema
26
-
27
- def command
28
- ["ALTER", index.name, "SCHEMA", "ADD", *field_schema]
29
- end
30
-
31
- def field_schema
32
- @field_schema ||= Schema.make_field(field_name, raw_schema).to_a
33
- end
27
+ attr_reader :index, :name, :type, :options, :block
34
28
  end
35
29
  end
@@ -3,8 +3,6 @@
3
3
  require "redis"
4
4
  require "active_support/notifications"
5
5
 
6
- require "redi_search/client/response"
7
-
8
6
  module RediSearch
9
7
  class Client
10
8
  def initialize(redis = Redis.new)
@@ -20,9 +18,9 @@ module RediSearch
20
18
  end
21
19
 
22
20
  def multi
23
- Response.new(redis.multi do
21
+ Response.new(redis.multi do |pipeline|
24
22
  instrument("pipeline", query: ["begin pipeline"])
25
- capture_pipeline { yield }
23
+ capture_pipeline(pipeline) { yield }
26
24
  instrument("pipeline", query: ["finish pipeline"])
27
25
  end)
28
26
  end
@@ -32,14 +30,18 @@ module RediSearch
32
30
  attr_reader :redis
33
31
  attr_accessor :pipeline
34
32
 
35
- def capture_pipeline
36
- self.pipeline = true
33
+ def capture_pipeline(pipeline)
34
+ self.pipeline = pipeline
37
35
  yield
38
36
  self.pipeline = false
39
37
  end
40
38
 
41
39
  def send_command(command, *params)
42
- Response.new(redis.call(command, *params))
40
+ if pipeline
41
+ Response.new(pipeline.call(command, *params))
42
+ else
43
+ Response.new(redis.call(command, *params))
44
+ end
43
45
  end
44
46
 
45
47
  def instrument(action, payload, &block)
@@ -47,7 +49,7 @@ module RediSearch
47
49
  "action.redi_search",
48
50
  { name: "RediSearch", action: action, inside_pipeline: pipeline }.
49
51
  merge(payload),
50
- &Proc.new(&(block || proc {})) # rubocop:disable Lint/EmptyBlock
52
+ &Proc.new(&(block || proc {}))
51
53
  )
52
54
  end
53
55
  end
@@ -4,9 +4,9 @@ module RediSearch
4
4
  class Document
5
5
  module Display
6
6
  def inspect
7
- inspection = pretty_print_attributes.map do |field_name|
7
+ inspection = pretty_print_attributes.filter_map do |field_name|
8
8
  "#{field_name}: #{public_send(field_name)}"
9
- end.compact.join(", ")
9
+ end.join(", ")
10
10
 
11
11
  "#<#{self.class} #{inspection}>"
12
12
  end
@@ -19,7 +19,7 @@ module RediSearch
19
19
  pp_attrs.compact
20
20
  end
21
21
 
22
- #:nocov:
22
+ # :nocov:
23
23
  def pretty_print(printer) # rubocop:disable Metrics/MethodLength
24
24
  printer.object_address_group(self) do
25
25
  printer.seplist(
@@ -35,7 +35,7 @@ module RediSearch
35
35
  end
36
36
  end
37
37
  end
38
- #:nocov:
38
+ # :nocov:
39
39
  end
40
40
  end
41
41
  end