redi_search 0.1.0 → 1.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +516 -112
  3. data/lib/redi_search.rb +5 -2
  4. data/lib/redi_search/add.rb +70 -0
  5. data/lib/redi_search/alter.rb +30 -0
  6. data/lib/redi_search/create.rb +53 -0
  7. data/lib/redi_search/document.rb +71 -16
  8. data/lib/redi_search/index.rb +31 -26
  9. data/lib/redi_search/lazily_load.rb +65 -0
  10. data/lib/redi_search/log_subscriber.rb +4 -0
  11. data/lib/redi_search/model.rb +41 -18
  12. data/lib/redi_search/schema.rb +17 -8
  13. data/lib/redi_search/schema/text_field.rb +0 -2
  14. data/lib/redi_search/search.rb +22 -44
  15. data/lib/redi_search/search/clauses.rb +60 -31
  16. data/lib/redi_search/search/clauses/and.rb +17 -0
  17. data/lib/redi_search/search/clauses/application_clause.rb +18 -0
  18. data/lib/redi_search/search/clauses/boolean.rb +72 -0
  19. data/lib/redi_search/search/clauses/highlight.rb +47 -0
  20. data/lib/redi_search/search/clauses/in_order.rb +17 -0
  21. data/lib/redi_search/search/clauses/language.rb +23 -0
  22. data/lib/redi_search/search/clauses/limit.rb +27 -0
  23. data/lib/redi_search/search/clauses/no_content.rb +17 -0
  24. data/lib/redi_search/search/clauses/no_stop_words.rb +17 -0
  25. data/lib/redi_search/search/clauses/or.rb +23 -0
  26. data/lib/redi_search/search/clauses/return.rb +23 -0
  27. data/lib/redi_search/search/clauses/slop.rb +23 -0
  28. data/lib/redi_search/search/clauses/sort_by.rb +25 -0
  29. data/lib/redi_search/search/clauses/verbatim.rb +17 -0
  30. data/lib/redi_search/search/clauses/where.rb +66 -0
  31. data/lib/redi_search/search/clauses/with_scores.rb +17 -0
  32. data/lib/redi_search/search/result.rb +46 -0
  33. data/lib/redi_search/search/term.rb +4 -4
  34. data/lib/redi_search/spellcheck.rb +30 -29
  35. data/lib/redi_search/spellcheck/result.rb +44 -0
  36. data/lib/redi_search/version.rb +1 -1
  37. metadata +101 -31
  38. data/.gitignore +0 -11
  39. data/.rubocop.yml +0 -1757
  40. data/.travis.yml +0 -23
  41. data/Gemfile +0 -17
  42. data/Rakefile +0 -12
  43. data/bin/console +0 -8
  44. data/bin/publish +0 -58
  45. data/bin/setup +0 -8
  46. data/bin/test +0 -7
  47. data/lib/redi_search/document/converter.rb +0 -26
  48. data/lib/redi_search/error.rb +0 -6
  49. data/lib/redi_search/result/collection.rb +0 -22
  50. data/lib/redi_search/search/and_clause.rb +0 -15
  51. data/lib/redi_search/search/boolean_clause.rb +0 -72
  52. data/lib/redi_search/search/highlight_clause.rb +0 -43
  53. data/lib/redi_search/search/or_clause.rb +0 -21
  54. data/lib/redi_search/search/where_clause.rb +0 -66
  55. data/redi_search.gemspec +0 -48
data/.travis.yml DELETED
@@ -1,23 +0,0 @@
1
- ---
2
- env:
3
- global:
4
- - CC_TEST_REPORTER_ID=fec34310f03fd2cc767a85fa23d5102f3dca67b9cc967a48d9940027731394e8
5
- sudo: false
6
- language: ruby
7
- cache: bundler
8
- rvm: 2.6.3
9
- before_install: gem install bundler -v 1.17.3
10
- services: docker
11
- before_script:
12
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
13
- - chmod +x ./cc-test-reporter
14
- - ./cc-test-reporter before-build
15
- before_install:
16
- - docker run -d -p 6379:6379 redislabs/redisearch:latest --protected-mode no --loadmodule /usr/lib/redis/modules/redisearch.so
17
- after_script:
18
- - if [[ "$TRAVIS_TEST_RESULT" == 0 ]]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT; fi
19
- script: bundle exec $COMMAND
20
- matrix:
21
- include:
22
- - env: COMMAND='rake test'
23
- - env: COMMAND=rubocop
data/Gemfile DELETED
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
6
-
7
- gemspec
8
-
9
- gem "faker"
10
- gem "minitest", "~> 5.0"
11
- gem "pry"
12
- gem "pry-rails"
13
- gem "rails", "~> 6.0.0.rc1"
14
- gem "rubocop"
15
- gem "rubocop-performance"
16
- gem "simplecov"
17
- gem "sqlite3"
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rake/testtask"
5
-
6
- Rake::TestTask.new(:test) do |t|
7
- t.libs << "test"
8
- t.libs << "lib"
9
- t.test_files = FileList["test/**/*_test.rb"]
10
- end
11
-
12
- task default: :test
data/bin/console DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "redi_search"
6
-
7
- require "pry"
8
- Pry.start
data/bin/publish DELETED
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "pathname"
5
- require "fileutils"
6
- require_relative "../lib/redi_search/version"
7
-
8
- # path to your application root.
9
- APP_ROOT = Pathname.new File.expand_path("..", __dir__)
10
- MASTER_CHECK = <<~MASTER_CHECK
11
- if [ $(git symbolic-ref --short -q HEAD) != 'master' ];
12
- then exit 1;
13
- fi
14
- MASTER_CHECK
15
- VERSION_TYPES = %w(major minor patch).freeze
16
-
17
- def system!(*args)
18
- system(*args) || abort("\n== Command #{args} failed ==")
19
- end
20
-
21
- abort("\n== Version Type incorrect ==") unless VERSION_TYPES.include?(ARGV[0])
22
-
23
- abort("\n== Not on master") unless system(MASTER_CHECK)
24
-
25
- current_version = RediSearch::VERSION.split(".").map(&:to_i)
26
-
27
- case ARGV[0]
28
- when "major"
29
- current_version[0] += 1
30
- current_version[1] = 0
31
- current_version[2] = 0
32
- when "minor"
33
- current_version[1] += 1
34
- current_version[2] = 0
35
- when "patch"
36
- current_version[2] += 1
37
- end
38
-
39
- FileUtils.chdir APP_ROOT do
40
- contents = <<~FILE
41
- # frozen_string_literal: true
42
-
43
- module RediSearch
44
- VERSION = "#{current_version.join('.')}"
45
- end
46
- FILE
47
-
48
- puts "== Updating version to #{current_version.join('.')} =="
49
- File.write("lib/redi_search/version.rb", contents)
50
-
51
- system! "git add lib/redi_search/version.rb"
52
-
53
- puts "== Committing updated files =="
54
- system! "git commit -m 'Version bump to #{current_version.join('.')}'"
55
-
56
- puts "== Tagging release =="
57
- system! "bundle exec rake release"
58
- end
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/bin/test DELETED
@@ -1,7 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- $: << File.expand_path("../test", __dir__)
5
-
6
- require "bundler/setup"
7
- require "rails/plugin/test"
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RediSearch
4
- class Document
5
- class Converter
6
- def initialize(index, record)
7
- @index = index
8
- @record = record
9
- end
10
-
11
- def document
12
- Document.new(
13
- index,
14
- record.id,
15
- index.schema.fields.map do |field|
16
- [field.to_s, record.public_send(field)]
17
- end.to_h
18
- )
19
- end
20
-
21
- private
22
-
23
- attr_reader :index, :record
24
- end
25
- end
26
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RediSearch
4
- class Error < StandardError
5
- end
6
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RediSearch
4
- class Result
5
- class Collection < Array
6
- def initialize(index, count, records)
7
- @count = count
8
- super(Hash[*records].map do |doc_id, fields|
9
- Document.new(index, doc_id, Hash[*fields])
10
- end)
11
- end
12
-
13
- def count
14
- @count || super
15
- end
16
-
17
- def size
18
- @count || super
19
- end
20
- end
21
- end
22
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "redi_search/search/boolean_clause"
4
-
5
- module RediSearch
6
- class Search
7
- class AndClause < BooleanClause
8
- private
9
-
10
- def operand
11
- " "
12
- end
13
- end
14
- end
15
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RediSearch
4
- class Search
5
- class BooleanClause
6
- def initialize(search, term, prior_clause = nil, **term_options)
7
- @search = search
8
- @prior_clause = prior_clause
9
- @not = false
10
-
11
- initialize_term(term, **term_options)
12
- end
13
-
14
- def to_s
15
- raise ArgumentError, "missing query terms" if term.blank?
16
-
17
- [
18
- prior_clause.presence,
19
- queryify_term.dup.prepend(not_operator)
20
- ].compact.join(operand)
21
- end
22
-
23
- def inspect
24
- to_s.inspect
25
- end
26
-
27
- def not(term, **term_options)
28
- @not = true
29
-
30
- initialize_term(term, **term_options)
31
-
32
- search
33
- end
34
-
35
- private
36
-
37
- attr_reader :prior_clause, :term, :search
38
-
39
- def operand
40
- raise NotImplementedError
41
- end
42
-
43
- def not_operator
44
- return "" unless @not
45
-
46
- "-"
47
- end
48
-
49
- def initialize_term(term, **term_options)
50
- return if term.blank?
51
-
52
- @term =
53
- if term.is_a? RediSearch::Search
54
- term
55
- else
56
- Term.new(term, term_options)
57
- end
58
- end
59
-
60
- def queryify_term
61
- if term.is_a?(RediSearch::Search) &&
62
- !term.term_clause.is_a?(RediSearch::Search::WhereClause)
63
- "(#{term.term_clause})"
64
- elsif term.is_a?(RediSearch::Search)
65
- term.term_clause
66
- else
67
- term
68
- end.to_s
69
- end
70
- end
71
- end
72
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RediSearch
4
- class Search
5
- class HighlightClause
6
- def initialize(**options)
7
- @options = options.to_h
8
-
9
- parse_options
10
- end
11
-
12
- def clause
13
- [
14
- "HIGHLIGHT",
15
- (fields_clause(**options[:fields]) if options.key?(:fields)),
16
- (tags_clause(**options[:tags]) if options.key? :tags),
17
- ].compact.flatten(1)
18
- end
19
-
20
- private
21
-
22
- attr_reader :options, :tags_args, :fields_args
23
-
24
- def parse_options
25
- return if options.except(:fields, :tags).empty?
26
-
27
- arg_error "Unsupported argument: #{options}"
28
- end
29
-
30
- def tags_clause(open:, close:)
31
- ["TAGS", open, close]
32
- end
33
-
34
- def fields_clause(num:, field:)
35
- ["FIELDS", num, field]
36
- end
37
-
38
- def arg_error(msg)
39
- raise ArgumentError, "Highlight: #{msg}"
40
- end
41
- end
42
- end
43
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "redi_search/search/boolean_clause"
4
-
5
- module RediSearch
6
- class Search
7
- class OrClause < BooleanClause
8
- def where(**condition)
9
- @term = search.dup.where(condition)
10
-
11
- search
12
- end
13
-
14
- private
15
-
16
- def operand
17
- "|"
18
- end
19
- end
20
- end
21
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RediSearch
4
- class Search
5
- class WhereClause
6
- def initialize(search, condition, prior_clause = nil)
7
- @search = search
8
- @prior_clause = prior_clause
9
- @not = false
10
-
11
- initialize_term(condition)
12
- end
13
-
14
- def to_s
15
- [
16
- prior_clause.presence,
17
- "(#{not_operator}@#{field}:#{queryify_term})"
18
- ].compact.join(" ")
19
- end
20
-
21
- def inspect
22
- to_s.inspect
23
- end
24
-
25
- def not(condition)
26
- @not = true
27
-
28
- initialize_term(condition)
29
-
30
- search
31
- end
32
-
33
- private
34
-
35
- attr_reader :prior_clause, :term, :field, :search
36
-
37
- def queryify_term
38
- if term.is_a? RediSearch::Search
39
- "(#{term.term_clause})"
40
- else
41
- term.to_s
42
- end
43
- end
44
-
45
- def not_operator
46
- return "" unless @not
47
-
48
- "-"
49
- end
50
-
51
- def initialize_term(condition)
52
- return if condition.blank?
53
-
54
- condition, *options = condition.to_a
55
-
56
- @field = condition[0]
57
- @term =
58
- if condition[1].is_a? RediSearch::Search
59
- condition[1]
60
- else
61
- Term.new(condition[1], **options.to_h)
62
- end
63
- end
64
- end
65
- end
66
- end
data/redi_search.gemspec DELETED
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path("lib", __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "redi_search/version"
6
-
7
- Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
8
- spec.name = "redi_search"
9
- spec.version = RediSearch::VERSION
10
- spec.authors = ["Nick Pezza"]
11
- spec.email = ["npezza93@gmail.com"]
12
-
13
- spec.summary = %q(RediSearch ruby wrapper that can integrate with Rails)
14
- spec.homepage = "https://github.com/npezza93/redi_search"
15
- spec.license = "MIT"
16
-
17
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the
18
- # 'allowed_push_host'
19
- # to allow pushing to a single host or delete this section to allow pushing to
20
- # any host.
21
- if spec.respond_to?(:metadata)
22
- spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = spec.homepage
24
- spec.metadata["changelog_uri"] =
25
- "https://github.com/npezza93/redi_search/blob/master/changelog.md"
26
- else
27
- raise "RubyGems 2.0 or newer is required to protect against " \
28
- "public gem pushes."
29
- end
30
-
31
- # Specify which files should be added to the gem when it is released.
32
- # The `git ls-files -z` loads the files in the RubyGem that have been added
33
- # into git.
34
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
35
- `git ls-files -z`.split("\x0").reject do |f|
36
- f.match(%r{^(test|spec|features)/})
37
- end
38
- end
39
- spec.bindir = "exe"
40
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
41
- spec.require_paths = ["lib"]
42
-
43
- spec.add_runtime_dependency "activesupport"
44
- spec.add_runtime_dependency "redis"
45
-
46
- spec.add_development_dependency "bundler", "~> 1.17"
47
- spec.add_development_dependency "rake", "~> 12.0"
48
- end