redi_search 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +516 -112
- data/lib/redi_search.rb +5 -2
- data/lib/redi_search/add.rb +70 -0
- data/lib/redi_search/alter.rb +30 -0
- data/lib/redi_search/create.rb +53 -0
- data/lib/redi_search/document.rb +71 -16
- data/lib/redi_search/index.rb +31 -26
- data/lib/redi_search/lazily_load.rb +65 -0
- data/lib/redi_search/log_subscriber.rb +4 -0
- data/lib/redi_search/model.rb +41 -18
- data/lib/redi_search/schema.rb +17 -8
- data/lib/redi_search/schema/text_field.rb +0 -2
- data/lib/redi_search/search.rb +22 -44
- data/lib/redi_search/search/clauses.rb +60 -31
- data/lib/redi_search/search/clauses/and.rb +17 -0
- data/lib/redi_search/search/clauses/application_clause.rb +18 -0
- data/lib/redi_search/search/clauses/boolean.rb +72 -0
- data/lib/redi_search/search/clauses/highlight.rb +47 -0
- data/lib/redi_search/search/clauses/in_order.rb +17 -0
- data/lib/redi_search/search/clauses/language.rb +23 -0
- data/lib/redi_search/search/clauses/limit.rb +27 -0
- data/lib/redi_search/search/clauses/no_content.rb +17 -0
- data/lib/redi_search/search/clauses/no_stop_words.rb +17 -0
- data/lib/redi_search/search/clauses/or.rb +23 -0
- data/lib/redi_search/search/clauses/return.rb +23 -0
- data/lib/redi_search/search/clauses/slop.rb +23 -0
- data/lib/redi_search/search/clauses/sort_by.rb +25 -0
- data/lib/redi_search/search/clauses/verbatim.rb +17 -0
- data/lib/redi_search/search/clauses/where.rb +66 -0
- data/lib/redi_search/search/clauses/with_scores.rb +17 -0
- data/lib/redi_search/search/result.rb +46 -0
- data/lib/redi_search/search/term.rb +4 -4
- data/lib/redi_search/spellcheck.rb +30 -29
- data/lib/redi_search/spellcheck/result.rb +44 -0
- data/lib/redi_search/version.rb +1 -1
- metadata +101 -31
- data/.gitignore +0 -11
- data/.rubocop.yml +0 -1757
- data/.travis.yml +0 -23
- data/Gemfile +0 -17
- data/Rakefile +0 -12
- data/bin/console +0 -8
- data/bin/publish +0 -58
- data/bin/setup +0 -8
- data/bin/test +0 -7
- data/lib/redi_search/document/converter.rb +0 -26
- data/lib/redi_search/error.rb +0 -6
- data/lib/redi_search/result/collection.rb +0 -22
- data/lib/redi_search/search/and_clause.rb +0 -15
- data/lib/redi_search/search/boolean_clause.rb +0 -72
- data/lib/redi_search/search/highlight_clause.rb +0 -43
- data/lib/redi_search/search/or_clause.rb +0 -21
- data/lib/redi_search/search/where_clause.rb +0 -66
- 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
data/bin/console
DELETED
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
data/bin/test
DELETED
@@ -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
|
data/lib/redi_search/error.rb
DELETED
@@ -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,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
|