redi_search 2.0.2 → 3.0.0

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: 7b7bc12a1d3a50de259ae10c27658e164d3ef84b65f0c4108c925138e53c1239
4
- data.tar.gz: 899ac067a70ee3f5d43c833a59aa32546ca4e18a57beaba3bccabc496ffff96a
3
+ metadata.gz: d3903d2f2ac5a8e6e8c82a507fbef8cad83d11b28a8e68dca6441844dc0b89cd
4
+ data.tar.gz: 6357b63845acdaea9df5d441154f77a3d5e353b2fed2c5e4cbbe58a5a6ad5071
5
5
  SHA512:
6
- metadata.gz: 131f1b1c9a4e2dad0740da6398a41a5ea01725e6e7dc02b9d604b252d3ad2612d3d23946fa1029e2d897c879b9b8c1c2951a73b1d7e4bca415d65998c0d8d0b8
7
- data.tar.gz: c1a6d747b27f77054c797feee442359306a36609fe1d8d8483467df93916ea4b2e7af7a1db5c3bd442aba04e54dad0131ac673dc6aa10ddba89b63ef48dbad37
6
+ metadata.gz: 94dc557ed0ee0ce1868ef92401928e68442eae74990595bfa26a26de4358f57526a8ef012203b67eae3ddbc6d576a2816b9715f41d140789d8fa3eed6ad09832
7
+ data.tar.gz: ae05dd2140a22dc5a73e9d90014eb580c0b3bc2276dc515d176efb767cb267a5ffa113cbabbf01fb1b7281e506dbf7798d26f9cbdad167b26afe550e608ecd8d
@@ -1,20 +1,18 @@
1
1
  name: lint
2
2
 
3
- on: [push]
3
+ on: [push,pull_request]
4
4
 
5
5
  jobs:
6
6
  lint:
7
7
  runs-on: ubuntu-latest
8
8
  steps:
9
- - uses: actions/checkout@v1
9
+ - uses: actions/checkout@v2
10
10
  - name: Set up Ruby 2.7
11
- uses: actions/setup-ruby@v1
11
+ uses: ruby/setup-ruby@v1
12
12
  with:
13
- ruby-version: 2.7.x
14
- - name: Install dependencies
13
+ ruby-version: 2.7
14
+ - name: Install rubocop
15
15
  run: |
16
- sudo apt-get install libsqlite3-dev
17
- gem install bundler --no-document
18
- bundle install
19
- - name: Run tests
20
- run: bundle exec rubocop --config=./.rubocop.yml --parallel
16
+ gem install rubocop rubocop-performance rubocop-minitest
17
+ - name: Lint
18
+ run: rubocop --config=./.rubocop.yml --parallel
@@ -1,20 +1,21 @@
1
1
  name: tests
2
2
 
3
- on: [push]
3
+ on: [push,pull_request]
4
4
 
5
5
  jobs:
6
6
  unit:
7
7
  runs-on: ubuntu-latest
8
8
  strategy:
9
9
  matrix:
10
- ruby: [ '2.5.x', '2.6.x', '2.7.x' ]
11
- gemfile: [ 'Gemfile', 'gemfiles/activerecord_51.gemfile', 'gemfiles/activerecord_52.gemfile' ]
10
+ ruby: [ '2.5', '2.6', '2.7' ]
11
+ gemfile: [ 'Gemfile', 'gemfiles/activerecord_51.gemfile', 'gemfiles/activerecord_52.gemfile', 'gemfiles/activerecord_61.gemfile' ]
12
12
  steps:
13
- - uses: actions/checkout@v1
13
+ - uses: actions/checkout@v2
14
14
  - name: Set up Ruby ${{ matrix.ruby }}
15
- uses: actions/setup-ruby@v1
15
+ uses: ruby/setup-ruby@v1
16
16
  with:
17
17
  ruby-version: ${{ matrix.ruby }}
18
+ bundler-cache: false
18
19
  - name: Install dependencies
19
20
  run: |
20
21
  sudo apt-get install libsqlite3-dev -y
@@ -24,21 +25,21 @@ jobs:
24
25
  run: BUNDLE_GEMFILE=${{ matrix.gemfile }} bundle exec rake test:unit
25
26
  integration:
26
27
  runs-on: ubuntu-latest
27
- strategy:
28
- matrix:
29
- redi_search: [ '1.4.28', '1.6.13', 'edge' ]
28
+ services:
29
+ redisearch:
30
+ image: redislabs/redisearch:2.0.2
31
+ ports:
32
+ - 6379:6379
30
33
  steps:
31
- - uses: actions/checkout@v1
34
+ - uses: actions/checkout@v2
32
35
  - name: Set up Ruby 2.7
33
- uses: actions/setup-ruby@v1
36
+ uses: ruby/setup-ruby@v1
34
37
  with:
35
- ruby-version: 2.7.x
38
+ ruby-version: 2.7
36
39
  - name: Install dependencies
37
40
  run: |
38
41
  sudo apt-get install libsqlite3-dev -y
39
- gem install bundler --no-document
40
42
  bundle install
41
- docker run -d -p 6379:6379 redislabs/redisearch:${{ matrix.redi_search }} --protected-mode no --loadmodule /usr/lib/redis/modules/redisearch.so
42
43
  - name: Run tests
43
44
  run: |
44
45
  bundle exec rake test:integration
@@ -1,6 +1,8 @@
1
1
  require:
2
+ - rubocop-minitest
2
3
  - rubocop-performance
3
4
  AllCops:
5
+ NewCops: enable
4
6
  Exclude:
5
7
  - vendor/**/*
6
8
  - Gemfile.lock
@@ -9,6 +11,7 @@ AllCops:
9
11
  - tmp/**/*
10
12
  - test/dummy/db/schema.rb
11
13
  - gemfiles/**/*
14
+ - bin/**/*
12
15
  TargetRubyVersion: 2.5
13
16
 
14
17
  # Department Bundler
@@ -611,7 +614,7 @@ Lint/UselessAssignment:
611
614
  StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars
612
615
  Enabled: true
613
616
 
614
- Lint/UselessComparison:
617
+ Lint/BinaryOperatorWithIdenticalOperands:
615
618
  Description: Checks for comparison of something with itself.
616
619
  Enabled: true
617
620
 
@@ -1197,9 +1200,6 @@ Style/MethodDefParentheses:
1197
1200
  StyleGuide: https://github.com/bbatsov/ruby-style-guide#method-parens
1198
1201
  Enabled: true
1199
1202
 
1200
- Style/MethodMissingSuper:
1201
- Enabled: true
1202
-
1203
1203
  Style/MissingRespondToMissing:
1204
1204
  Enabled: true
1205
1205
 
@@ -1630,5 +1630,70 @@ Style/RedundantRegexpCharacterClass:
1630
1630
  Enabled: true
1631
1631
  Style/RedundantRegexpEscape:
1632
1632
  Enabled: true
1633
+ Lint/MissingSuper:
1634
+ Enabled: false
1635
+
1636
+
1637
+
1638
+ Lint/DuplicateElsifCondition:
1639
+ Enabled: true
1640
+ Lint/DuplicateRescueException:
1641
+ Enabled: true
1642
+ Lint/EmptyConditionalBody:
1643
+ Enabled: true
1644
+ Lint/FloatComparison:
1645
+ Enabled: true
1646
+ Lint/OutOfRangeRegexpRef:
1647
+ Enabled: true
1648
+ Lint/SelfAssignment:
1649
+ Enabled: true
1650
+ Lint/TopLevelReturnWithArgument:
1651
+ Enabled: true
1652
+ Lint/UnreachableLoop:
1653
+ Enabled: true
1654
+ Style/AccessorGrouping:
1655
+ Enabled: true
1656
+ Style/ArrayCoercion:
1657
+ Enabled: true
1658
+ Style/BisectedAttrAccessor:
1659
+ Enabled: true
1660
+ Style/CaseLikeIf:
1661
+ Enabled: true
1662
+ Style/ExplicitBlockArgument:
1663
+ Enabled: false
1664
+ Style/GlobalStdStream:
1665
+ Enabled: true
1666
+ Style/HashAsLastArrayItem:
1667
+ Enabled: false
1668
+ Style/HashLikeCase:
1669
+ Enabled: true
1670
+ Style/OptionalBooleanParameter:
1671
+ Enabled: true
1672
+ Style/RedundantAssignment:
1673
+ Enabled: true
1633
1674
  Style/RedundantFetchBlock:
1634
1675
  Enabled: true
1676
+ Style/RedundantFileExtensionInRequire:
1677
+ Enabled: true
1678
+ Style/SingleArgumentDig:
1679
+ Enabled: true
1680
+ Style/StringConcatenation:
1681
+ Enabled: true
1682
+ Performance/AncestorsInclude:
1683
+ Enabled: true
1684
+ Performance/BigDecimalWithNumericArgument:
1685
+ Enabled: true
1686
+ Performance/RedundantSortBlock:
1687
+ Enabled: true
1688
+ Performance/RedundantStringChars:
1689
+ Enabled: true
1690
+ Performance/ReverseFirst:
1691
+ Enabled: true
1692
+ Performance/SortReverse:
1693
+ Enabled: true
1694
+ Performance/Squeeze:
1695
+ Enabled: true
1696
+ Performance/StringInclude:
1697
+ Enabled: true
1698
+ Minitest/AssertionInLifecycleHook:
1699
+ Enabled: false
data/Appraisals CHANGED
@@ -7,3 +7,7 @@ end
7
7
  appraise "activerecord-51" do
8
8
  gem "activerecord", "< 5.2", ">= 5.1"
9
9
  end
10
+
11
+ appraise "activerecord-61" do
12
+ gem "activerecord", "6.1.0.rc1"
13
+ end
data/Gemfile CHANGED
@@ -11,6 +11,7 @@ gem "faker"
11
11
  gem "mocha"
12
12
  gem "pry"
13
13
  gem "rubocop"
14
+ gem "rubocop-minitest"
14
15
  gem "rubocop-performance"
15
16
  gem "simplecov"
16
17
  gem "sqlite3"
data/README.md CHANGED
@@ -7,7 +7,6 @@
7
7
  # RediSearch
8
8
 
9
9
  ![Build Status](https://github.com/npezza93/redi_search/workflows/tests/badge.svg)
10
- [![Test Coverage](https://api.codeclimate.com/v1/badges/c6437acac5684de2549d/test_coverage)](https://codeclimate.com/github/npezza93/redi_search/test_coverage)
11
10
  [![Maintainability](https://api.codeclimate.com/v1/badges/c6437acac5684de2549d/maintainability)](https://codeclimate.com/github/npezza93/redi_search/maintainability)
12
11
 
13
12
  A simple, but powerful, Ruby wrapper around RediSearch, a search engine on top of
@@ -244,13 +243,11 @@ With no options: `{ place: :geo }`
244
243
 
245
244
  ## Document
246
245
 
247
- A `Document` is the Ruby representation of a RediSearch document.
246
+ A `Document` is the Ruby representation of a Redis hash.
248
247
 
249
- You can fetch a `Document` using `.get` or `.mget` class methods.
248
+ You can fetch a `Document` using `.get` class methods.
250
249
  - `get(index, document_id)` fetches a single `Document` in an `Index` for a
251
250
  given `document_id`.
252
- - `mget(index, *document_ids)` fetches a collection of `Document`s
253
- in an `Index` for the given `document_ids`.
254
251
 
255
252
  You can also make a `Document` instance using the
256
253
  `.for_object(index, record, serializer: nil, only: [])` class method. It takes
@@ -269,10 +266,7 @@ to override each other. There is also a `#document_id_without_index` method
269
266
  which removes the prepended index name.
270
267
 
271
268
  Finally there is a `#del` method that will remove the `Document` from the
272
- `Index`. It optionally accepts a `delete_document` named argument that signifies
273
- whether the `Document` should be completely removed from the Redis instance vs
274
- just the `Index`.
275
-
269
+ `Index`.
276
270
 
277
271
  ## Index
278
272
 
@@ -314,42 +308,32 @@ RediSearch::Index.new(name_of_index, schema)
314
308
  - If set, we avoid saving the term frequencies in the index. This saves
315
309
  memory but does not allow sorting based on the frequencies of a given
316
310
  term within the document.
317
- - `drop`
311
+ - `drop(keep_docs: false)`
318
312
  - Drops the `Index` from the Redis instance, returns a boolean. Has an
319
313
  accompanying bang method that will raise an exception upon failure. Will
320
- return `false` if the `Index` has already been dropped.
314
+ return `false` if the `Index` has already been dropped. Takes an option
315
+ keyword arg, `keep_docs`, that will by default remove all the document
316
+ hashes in Redis.
321
317
  - `exist?`
322
318
  - Returns a boolean signifying `Index` existence.
323
319
  - `info`
324
320
  - Returns a struct object with all the information about the `Index`.
325
321
  - `fields`
326
322
  - Returns an array of the field names in the `Index`.
327
- - `add(document, score: 1.0, replace: {}, language: nil, no_save: false)`
328
- - Takes a `Document` object and options. Has an
323
+ - `add(document)`
324
+ - Takes a `Document` object. Has an
329
325
  accompanying bang method that will raise an exception upon failure.
330
- - `score` -> The `Document`'s rank, a value between 0.0 and 1.0
331
- - `language` -> Use a stemmer for the supplied language during indexing.
332
- - `no_save` -> Don't save the actual `Document` in the database and only index it.
333
- - `replace` -> Accepts a boolean or a hash. If a truthy value is passed, we
334
- will do an UPSERT style insertion - and delete an older version of the
335
- `Document` if it exists.
336
- - `replace: { partial: true }` -> Allows you to not have to specify all
337
- fields for reindexing. Fields not given to the command will be loaded from
338
- the current version of the `Document`.
339
- - `add_multiple(documents, score: 1.0, replace: {}, language: nil, no_save: false)`
326
+ - `add_multiple(documents)`
340
327
  - Takes an array of `Document` objects. This provides a more performant way to
341
328
  add multiple documents to the `Index`. Accepts the same options as `add`.
342
- - `del(document, delete_document: false)`
343
- - Removes a `Document` from the `Index`. `delete_document` signifies whether the
344
- `Document` should be completely removed from the Redis instance vs just the
345
- `Index`.
329
+ - `del(document)`
330
+ - Removes a `Document` from the `Index`.
346
331
  - `document_count`
347
332
  - Returns the number of `Document`s in the `Index`
348
333
  - `add_field(field_name, schema)`
349
334
  - Adds a new field to the `Index`. Ex: `index.add_field(:first_name, text: { phonetic: "dm:en" })`
350
- - `reindex(documents, recreate: false, **options)`
335
+ - `reindex(documents, recreate: false)`
351
336
  - If `recreate` is `true` the `Index` will be dropped and recreated
352
- - `options` accepts the same options as `add`
353
337
 
354
338
 
355
339
  ## Searching
@@ -521,11 +505,9 @@ end
521
505
  This will automatically add `User.search` and `User.spellcheck`
522
506
  methods which behave the same as if you called them on an `Index` instance.
523
507
 
524
- `User.reindex(recreate: false, only: [], **options)` is also added and behaves
508
+ `User.reindex(recreate: false, only: [])` is also added and behaves
525
509
  similarly to `RediSearch::Index#reindex`. Some of the differences include:
526
- - By default, does an upsert for all `Document`s added using the
527
- option `replace: { partial: true }`.
528
- - `Document`s do not to be passed as the first parameter. The `search_import`
510
+ - `Document`s do not need to be passed as the first parameter. The `search_import`
529
511
  scope is automatically called and all the records are converted
530
512
  to `Document`s.
531
513
  - Accepts an optional `only` parameter where you can specify a limited number
@@ -2,9 +2,12 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "appraisal", "~> 2.2"
6
+ gem "faker"
5
7
  gem "mocha"
6
8
  gem "pry"
7
9
  gem "rubocop"
10
+ gem "rubocop-minitest"
8
11
  gem "rubocop-performance"
9
12
  gem "simplecov"
10
13
  gem "sqlite3"
@@ -2,9 +2,12 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "appraisal", "~> 2.2"
6
+ gem "faker"
5
7
  gem "mocha"
6
8
  gem "pry"
7
9
  gem "rubocop"
10
+ gem "rubocop-minitest"
8
11
  gem "rubocop-performance"
9
12
  gem "simplecov"
10
13
  gem "sqlite3"
@@ -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 "faker"
7
+ gem "mocha"
8
+ gem "pry"
9
+ gem "rubocop"
10
+ gem "rubocop-minitest"
11
+ gem "rubocop-performance"
12
+ gem "simplecov"
13
+ gem "sqlite3"
14
+ gem "activerecord", "6.1.0.rc1"
15
+
16
+ gemspec path: "../"
@@ -9,10 +9,12 @@ module RediSearch
9
9
  class Client
10
10
  def initialize(redis = Redis.new)
11
11
  @redis = redis
12
+ @pipeline = false
12
13
  end
13
14
 
14
- def call!(command, *params)
15
+ def call!(command, *params, skip_ft: false)
15
16
  instrument(command.downcase, query: [command, params]) do
17
+ command = "FT.#{command}" unless skip_ft
16
18
  send_command(command, *params)
17
19
  end
18
20
  end
@@ -20,24 +22,32 @@ module RediSearch
20
22
  def multi
21
23
  Response.new(redis.multi do
22
24
  instrument("pipeline", query: ["begin pipeline"])
23
- yield
25
+ capture_pipeline { yield }
24
26
  instrument("pipeline", query: ["finish pipeline"])
25
27
  end)
26
28
  end
27
29
 
28
30
  private
29
31
 
30
- attr_reader :redis
32
+ attr_reader :redis
33
+ attr_accessor :pipeline
34
+
35
+ def capture_pipeline
36
+ self.pipeline = true
37
+ yield
38
+ self.pipeline = false
39
+ end
31
40
 
32
41
  def send_command(command, *params)
33
- Response.new(redis.call("FT.#{command}", *params))
42
+ Response.new(redis.call(command, *params))
34
43
  end
35
44
 
36
45
  def instrument(action, payload, &block)
37
46
  ActiveSupport::Notifications.instrument(
38
47
  "action.redi_search",
39
- { name: "RediSearch", action: action }.merge(payload),
40
- &Proc.new(&(block || proc {}))
48
+ { name: "RediSearch", action: action, inside_pipeline: pipeline }.
49
+ merge(payload),
50
+ &Proc.new(&(block || proc {})) # rubocop:disable Lint/EmptyBlock
41
51
  )
42
52
  end
43
53
  end
@@ -6,7 +6,7 @@ module RediSearch
6
6
  def ok?
7
7
  case response
8
8
  when String then response == "OK"
9
- when Integer then response == 1
9
+ when Integer then response >= 1
10
10
  when Array then array_ok?
11
11
  else response
12
12
  end
@@ -31,7 +31,8 @@ module RediSearch
31
31
  attr_reader :index, :schema, :options
32
32
 
33
33
  def command
34
- ["CREATE", index.name, *extract_options.compact, "SCHEMA", schema.to_a]
34
+ ["CREATE", index.name, "ON", "HASH", "PREFIX", 1, index.name,
35
+ *extract_options.compact, "SCHEMA", schema.to_a]
35
36
  end
36
37
 
37
38
  def extract_options
@@ -23,10 +23,6 @@ module RediSearch
23
23
  def get(index, document_id)
24
24
  Finder.new(index, document_id).find
25
25
  end
26
-
27
- def mget(index, *document_ids)
28
- Finder.new(index, *document_ids).find
29
- end
30
26
  end
31
27
 
32
28
  attr_reader :attributes, :score
@@ -40,9 +36,8 @@ module RediSearch
40
36
  load_attributes
41
37
  end
42
38
 
43
- def del(delete_document: false)
44
- command = ["DEL", index.name, document_id, ("DD" if delete_document)]
45
- call!(*command.compact).ok?
39
+ def del
40
+ RediSearch.client.call!("DEL", document_id, skip_ft: true).ok?
46
41
  end
47
42
 
48
43
  def schema_fields
@@ -73,10 +68,6 @@ module RediSearch
73
68
 
74
69
  attr_reader :index
75
70
 
76
- def call!(*command)
77
- RediSearch.client.call!(*command)
78
- end
79
-
80
71
  def load_attributes
81
72
  attributes.each do |field, value|
82
73
  next unless schema_fields.include? field.to_s
@@ -3,75 +3,37 @@
3
3
  module RediSearch
4
4
  class Document
5
5
  class Finder
6
- def initialize(index, *document_ids)
6
+ def initialize(index, document_id)
7
7
  @index = index
8
- @document_ids = [*document_ids]
8
+ @document_id = document_id
9
9
  end
10
10
 
11
11
  def find
12
- if multi?
13
- parse_multi_documents
14
- else
15
- parse_document(document_ids.first, response)
16
- end
12
+ Document.new(index, document_id, Hash[*response]) if response?
17
13
  end
18
14
 
19
15
  private
20
16
 
21
- attr_reader :index, :document_ids
17
+ attr_reader :index, :document_id
22
18
 
23
19
  def response
24
- @response ||= call!(get_command, index.name, *prepended_document_ids)
20
+ @response ||= call!("HGETALL", prepended_document_id)
25
21
  end
26
22
 
27
23
  def call!(*command)
28
- RediSearch.client.call!(*command)
29
- end
30
-
31
- def get_command
32
- if multi?
33
- "MGET"
34
- else
35
- "GET"
36
- end
37
- end
38
-
39
- def multi?
40
- document_ids.size > 1
41
- end
42
-
43
- def prepended_document_ids
44
- document_ids.map do |document_id|
45
- prepend_document_id(document_id)
46
- end
24
+ RediSearch.client.call!(*command, skip_ft: true)
47
25
  end
48
26
 
49
- def prepend_document_id(id)
50
- if id.to_s.start_with? index.name
51
- id
27
+ def prepended_document_id
28
+ if document_id.to_s.start_with? index.name
29
+ document_id
52
30
  else
53
- "#{index.name}#{id}"
31
+ "#{index.name}#{document_id}"
54
32
  end
55
33
  end
56
34
 
57
- def parse_multi_documents
58
- document_ids.map.with_index do |document_id, index|
59
- parse_document(document_id, response[index])
60
- end.compact
61
- end
62
-
63
- def parse_document(document_id, document_response)
64
- return unless document_response?(document_response)
65
-
66
- Document.new(index, document_id, Hash[*document_response])
67
- end
68
-
69
- def document_response?(document_response)
70
- if document_response.respond_to?(:empty?)
71
- !document_response.empty?
72
- else
73
- !document_response.nil?
74
- end
35
+ def response?
36
+ !response.to_a.empty?
75
37
  end
76
38
  end
77
39
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RediSearch
4
+ class Hset
5
+ def initialize(index, document)
6
+ @index = index
7
+ @document = document
8
+ end
9
+
10
+ def call!
11
+ RediSearch.client.call!(*command, skip_ft: true)
12
+ end
13
+
14
+ def call
15
+ call!
16
+ rescue Redis::CommandError
17
+ false
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :index, :document
23
+
24
+ def command
25
+ ["HSET", document.document_id, document.redis_attributes].compact
26
+ end
27
+ end
28
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "redi_search/add"
3
+ require "redi_search/hset"
4
4
  require "redi_search/create"
5
5
  require "redi_search/schema"
6
6
  require "redi_search/search"
@@ -33,34 +33,36 @@ module RediSearch
33
33
  Create.new(self, schema, options).call!
34
34
  end
35
35
 
36
- def drop
37
- drop!
36
+ def drop(keep_docs: false)
37
+ drop!(keep_docs: keep_docs)
38
38
  rescue Redis::CommandError
39
39
  false
40
40
  end
41
41
 
42
- def drop!
43
- client.call!("DROP", name).ok?
42
+ def drop!(keep_docs: false)
43
+ command = ["DROPINDEX", name]
44
+ command << "DD" unless keep_docs
45
+ client.call!(*command.compact).ok?
44
46
  end
45
47
 
46
- def add(document, **options)
47
- Add.new(self, document, **options).call
48
+ def add(document)
49
+ Hset.new(self, document).call
48
50
  end
49
51
 
50
- def add!(document, **options)
51
- Add.new(self, document, **options).call!
52
+ def add!(document)
53
+ Hset.new(self, document).call!
52
54
  end
53
55
 
54
- def add_multiple(documents, **options)
56
+ def add_multiple(documents)
55
57
  client.multi do
56
58
  documents.each do |document|
57
- add(document, **options)
59
+ add(document)
58
60
  end
59
- end.ok?
61
+ end.all? { |response| response >= 0 }
60
62
  end
61
63
 
62
- def del(document, delete_document: false)
63
- document.del(delete_document: delete_document)
64
+ def del(document)
65
+ document.del
64
66
  end
65
67
 
66
68
  def exist?
@@ -81,11 +83,11 @@ module RediSearch
81
83
  schema.fields.map(&:to_s)
82
84
  end
83
85
 
84
- def reindex(documents, recreate: false, **options)
86
+ def reindex(documents, recreate: false)
85
87
  drop if recreate
86
88
  create unless exist?
87
89
 
88
- add_multiple documents, **options
90
+ add_multiple documents
89
91
  end
90
92
 
91
93
  def document_count
@@ -39,9 +39,9 @@ module RediSearch
39
39
  def action_color(action)
40
40
  case action.to_sym
41
41
  when :search, :spellcheck then YELLOW
42
- when :create, :add then GREEN
43
- when :drop, :del then RED
44
- when :get, :mget, :info then CYAN
42
+ when :create, :hset then GREEN
43
+ when :dropindex, :del then RED
44
+ when :hgetall, :info then CYAN
45
45
  when :pipeline then MAGENTA
46
46
  when :explaincli then BLUE
47
47
  end
@@ -52,6 +52,7 @@ module RediSearch
52
52
  event.payload[:query].flatten.map.with_index do |arg, i|
53
53
  arg = "FT.#{arg}" if prepend_ft?(arg, i)
54
54
  arg = arg.inspect if inspect_arg?(event.payload, arg)
55
+ arg = " #{arg}" if event.payload[:inside_pipeline]
55
56
  arg
56
57
  end.join(" ")
57
58
  end
@@ -61,7 +62,7 @@ module RediSearch
61
62
  end
62
63
 
63
64
  def prepend_ft?(arg, index)
64
- index.zero? && !multiword?(arg)
65
+ index.zero? && !multiword?(arg) && %w(HSET HGETALL DEL).exclude?(arg.to_s)
65
66
  end
66
67
 
67
68
  def inspect_arg?(payload, arg)
@@ -48,11 +48,11 @@ module RediSearch
48
48
  redi_search_index.spellcheck(term, distance: distance)
49
49
  end
50
50
 
51
- def reindex(recreate: false, only: [], **options)
51
+ def reindex(recreate: false, only: [])
52
52
  search_import.find_in_batches.all? do |group|
53
53
  redi_search_index.reindex(
54
54
  group.map { |record| record.redi_search_document(only: only) },
55
- recreate: recreate, **options.deep_merge(replace: { partial: true })
55
+ recreate: recreate
56
56
  )
57
57
  end
58
58
  end
@@ -67,17 +67,11 @@ module RediSearch
67
67
  end
68
68
 
69
69
  def redi_search_delete_document
70
- return unless self.class.redi_search_index.exist?
71
-
72
- self.class.redi_search_index.del(
73
- redi_search_document, delete_document: true
74
- )
70
+ self.class.redi_search_index.del(redi_search_document)
75
71
  end
76
72
 
77
73
  def redi_search_add_document
78
- return unless self.class.redi_search_index.exist?
79
-
80
- self.class.redi_search_index.add(redi_search_document, replace: true)
74
+ self.class.redi_search_index.add(redi_search_document)
81
75
  end
82
76
  end
83
77
  end
@@ -48,7 +48,7 @@ module RediSearch
48
48
  @term = if term.is_a? RediSearch::Search
49
49
  term
50
50
  else
51
- Term.new(term, term_options)
51
+ Term.new(term, **term_options)
52
52
  end
53
53
  end
54
54
 
@@ -65,10 +65,10 @@ module RediSearch
65
65
  end
66
66
 
67
67
  def queryify_search
68
- if !term.term_clause.is_a?(RediSearch::Search::Clauses::Where)
69
- "(#{term.term_clause})"
70
- else
68
+ if term.term_clause.is_a?(RediSearch::Search::Clauses::Where)
71
69
  term.term_clause
70
+ else
71
+ "(#{term.term_clause})"
72
72
  end
73
73
  end
74
74
  end
@@ -7,7 +7,7 @@ module RediSearch
7
7
  module Clauses
8
8
  class Or < Boolean
9
9
  def where(**condition)
10
- @term = search.dup.where(condition)
10
+ @term = search.dup.where(**condition)
11
11
 
12
12
  search
13
13
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RediSearch
4
- VERSION = "2.0.2"
4
+ VERSION = "3.0.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redi_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Pezza
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-26 00:00:00.000000000 Z
11
+ date: 2020-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -98,7 +98,7 @@ dependencies:
98
98
  - - "~>"
99
99
  - !ruby/object:Gem::Version
100
100
  version: '13.0'
101
- description:
101
+ description:
102
102
  email: npezza93@gmail.com
103
103
  executables: []
104
104
  extensions: []
@@ -123,8 +123,8 @@ files:
123
123
  - gemfiles/.bundle/config
124
124
  - gemfiles/activerecord_51.gemfile
125
125
  - gemfiles/activerecord_52.gemfile
126
+ - gemfiles/activerecord_61.gemfile
126
127
  - lib/redi_search.rb
127
- - lib/redi_search/add.rb
128
128
  - lib/redi_search/add_field.rb
129
129
  - lib/redi_search/client.rb
130
130
  - lib/redi_search/client/response.rb
@@ -133,6 +133,7 @@ files:
133
133
  - lib/redi_search/document.rb
134
134
  - lib/redi_search/document/display.rb
135
135
  - lib/redi_search/document/finder.rb
136
+ - lib/redi_search/hset.rb
136
137
  - lib/redi_search/index.rb
137
138
  - lib/redi_search/lazily_load.rb
138
139
  - lib/redi_search/log_subscriber.rb
@@ -179,7 +180,7 @@ metadata:
179
180
  homepage_uri: https://github.com/npezza93/redi_search
180
181
  source_code_uri: https://github.com/npezza93/redi_search
181
182
  changelog_uri: https://github.com/npezza93/redi_search/releases
182
- post_install_message:
183
+ post_install_message:
183
184
  rdoc_options: []
184
185
  require_paths:
185
186
  - lib
@@ -194,8 +195,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
194
195
  - !ruby/object:Gem::Version
195
196
  version: '0'
196
197
  requirements: []
197
- rubygems_version: 3.1.2
198
- signing_key:
198
+ rubygems_version: 3.1.4
199
+ signing_key:
199
200
  specification_version: 4
200
201
  summary: RediSearch ruby wrapper that can integrate with Rails
201
202
  test_files: []
@@ -1,67 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "redi_search/validatable"
4
-
5
- module RediSearch
6
- class Add
7
- include Validatable
8
-
9
- validates_numericality_of :score, within: 0.0..1.0
10
-
11
- def initialize(index, document, score: 1.0, replace: {}, language: nil,
12
- no_save: false)
13
- @index = index
14
- @document = document
15
- @score = score || 1.0
16
- @replace = replace
17
- @language = language
18
- @no_save = no_save
19
- end
20
-
21
- def call!
22
- validate!
23
-
24
- RediSearch.client.call!(*command).ok?
25
- end
26
-
27
- def call
28
- call!
29
- rescue Redis::CommandError
30
- false
31
- end
32
-
33
- private
34
-
35
- attr_reader :index, :document, :score, :replace, :language, :no_save
36
-
37
- def command
38
- ["ADD", index.name, document.document_id, score, *extract_options,
39
- "FIELDS", document.redis_attributes].compact
40
- end
41
-
42
- def extract_options
43
- opts = []
44
- opts << ["LANGUAGE", language] if language
45
- opts << "NOSAVE" if no_save
46
- opts << replace_options if replace?
47
- opts
48
- end
49
-
50
- def replace?
51
- if replace.respond_to?(:empty?)
52
- !replace.empty?
53
- else
54
- replace
55
- end
56
- end
57
-
58
- def replace_options
59
- ["REPLACE"].tap do |replace_option|
60
- if replace.is_a?(Hash)
61
- replace_option << "PARTIAL" if replace[:partial]
62
- # replace_option << "NOCREATE" if replace[:no_create]
63
- end
64
- end
65
- end
66
- end
67
- end