redi_search 2.0.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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