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 +4 -4
- data/.github/workflows/lint.yml +8 -10
- data/.github/workflows/tests.yml +14 -13
- data/.rubocop.yml +69 -4
- data/Appraisals +4 -0
- data/Gemfile +1 -0
- data/README.md +15 -33
- data/gemfiles/activerecord_51.gemfile +3 -0
- data/gemfiles/activerecord_52.gemfile +3 -0
- data/gemfiles/activerecord_61.gemfile +16 -0
- data/lib/redi_search/client.rb +16 -6
- data/lib/redi_search/client/response.rb +1 -1
- data/lib/redi_search/create.rb +2 -1
- data/lib/redi_search/document.rb +2 -11
- data/lib/redi_search/document/finder.rb +12 -50
- data/lib/redi_search/hset.rb +28 -0
- data/lib/redi_search/index.rb +18 -16
- data/lib/redi_search/log_subscriber.rb +5 -4
- data/lib/redi_search/model.rb +4 -10
- data/lib/redi_search/search/clauses/boolean.rb +4 -4
- data/lib/redi_search/search/clauses/or.rb +1 -1
- data/lib/redi_search/version.rb +1 -1
- metadata +9 -8
- data/lib/redi_search/add.rb +0 -67
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3903d2f2ac5a8e6e8c82a507fbef8cad83d11b28a8e68dca6441844dc0b89cd
|
4
|
+
data.tar.gz: 6357b63845acdaea9df5d441154f77a3d5e353b2fed2c5e4cbbe58a5a6ad5071
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94dc557ed0ee0ce1868ef92401928e68442eae74990595bfa26a26de4358f57526a8ef012203b67eae3ddbc6d576a2816b9715f41d140789d8fa3eed6ad09832
|
7
|
+
data.tar.gz: ae05dd2140a22dc5a73e9d90014eb580c0b3bc2276dc515d176efb767cb267a5ffa113cbabbf01fb1b7281e506dbf7798d26f9cbdad167b26afe550e608ecd8d
|
data/.github/workflows/lint.yml
CHANGED
@@ -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@
|
9
|
+
- uses: actions/checkout@v2
|
10
10
|
- name: Set up Ruby 2.7
|
11
|
-
uses:
|
11
|
+
uses: ruby/setup-ruby@v1
|
12
12
|
with:
|
13
|
-
ruby-version: 2.7
|
14
|
-
- name: Install
|
13
|
+
ruby-version: 2.7
|
14
|
+
- name: Install rubocop
|
15
15
|
run: |
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
data/.github/workflows/tests.yml
CHANGED
@@ -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
|
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@
|
13
|
+
- uses: actions/checkout@v2
|
14
14
|
- name: Set up Ruby ${{ matrix.ruby }}
|
15
|
-
uses:
|
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
|
-
|
28
|
-
|
29
|
-
|
28
|
+
services:
|
29
|
+
redisearch:
|
30
|
+
image: redislabs/redisearch:2.0.2
|
31
|
+
ports:
|
32
|
+
- 6379:6379
|
30
33
|
steps:
|
31
|
-
- uses: actions/checkout@
|
34
|
+
- uses: actions/checkout@v2
|
32
35
|
- name: Set up Ruby 2.7
|
33
|
-
uses:
|
36
|
+
uses: ruby/setup-ruby@v1
|
34
37
|
with:
|
35
|
-
ruby-version: 2.7
|
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
|
data/.rubocop.yml
CHANGED
@@ -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/
|
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
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -7,7 +7,6 @@
|
|
7
7
|
# RediSearch
|
8
8
|
|
9
9
|

|
10
|
-
[](https://codeclimate.com/github/npezza93/redi_search/test_coverage)
|
11
10
|
[](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
|
246
|
+
A `Document` is the Ruby representation of a Redis hash.
|
248
247
|
|
249
|
-
You can fetch a `Document` using `.get`
|
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`.
|
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
|
328
|
-
- Takes a `Document` object
|
323
|
+
- `add(document)`
|
324
|
+
- Takes a `Document` object. Has an
|
329
325
|
accompanying bang method that will raise an exception upon failure.
|
330
|
-
|
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
|
343
|
-
- Removes a `Document` from the `Index`.
|
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
|
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: []
|
508
|
+
`User.reindex(recreate: false, only: [])` is also added and behaves
|
525
509
|
similarly to `RediSearch::Index#reindex`. Some of the differences include:
|
526
|
-
-
|
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
|
@@ -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: "../"
|
data/lib/redi_search/client.rb
CHANGED
@@ -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
|
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(
|
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 }.
|
40
|
-
|
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
|
data/lib/redi_search/create.rb
CHANGED
@@ -31,7 +31,8 @@ module RediSearch
|
|
31
31
|
attr_reader :index, :schema, :options
|
32
32
|
|
33
33
|
def command
|
34
|
-
["CREATE", index.name,
|
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
|
data/lib/redi_search/document.rb
CHANGED
@@ -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
|
44
|
-
|
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,
|
6
|
+
def initialize(index, document_id)
|
7
7
|
@index = index
|
8
|
-
@
|
8
|
+
@document_id = document_id
|
9
9
|
end
|
10
10
|
|
11
11
|
def find
|
12
|
-
if
|
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, :
|
17
|
+
attr_reader :index, :document_id
|
22
18
|
|
23
19
|
def response
|
24
|
-
@response ||= call!(
|
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
|
50
|
-
if
|
51
|
-
|
27
|
+
def prepended_document_id
|
28
|
+
if document_id.to_s.start_with? index.name
|
29
|
+
document_id
|
52
30
|
else
|
53
|
-
"#{index.name}#{
|
31
|
+
"#{index.name}#{document_id}"
|
54
32
|
end
|
55
33
|
end
|
56
34
|
|
57
|
-
def
|
58
|
-
|
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
|
data/lib/redi_search/index.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "redi_search/
|
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
|
-
|
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
|
47
|
-
|
48
|
+
def add(document)
|
49
|
+
Hset.new(self, document).call
|
48
50
|
end
|
49
51
|
|
50
|
-
def add!(document
|
51
|
-
|
52
|
+
def add!(document)
|
53
|
+
Hset.new(self, document).call!
|
52
54
|
end
|
53
55
|
|
54
|
-
def add_multiple(documents
|
56
|
+
def add_multiple(documents)
|
55
57
|
client.multi do
|
56
58
|
documents.each do |document|
|
57
|
-
add(document
|
59
|
+
add(document)
|
58
60
|
end
|
59
|
-
end.
|
61
|
+
end.all? { |response| response >= 0 }
|
60
62
|
end
|
61
63
|
|
62
|
-
def del(document
|
63
|
-
document.del
|
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
|
86
|
+
def reindex(documents, recreate: false)
|
85
87
|
drop if recreate
|
86
88
|
create unless exist?
|
87
89
|
|
88
|
-
add_multiple documents
|
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, :
|
43
|
-
when :
|
44
|
-
when :
|
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)
|
data/lib/redi_search/model.rb
CHANGED
@@ -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: []
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
data/lib/redi_search/version.rb
CHANGED
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:
|
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-
|
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.
|
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: []
|
data/lib/redi_search/add.rb
DELETED
@@ -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
|