redisearch-rb 0.1.8 → 0.2.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/.travis.yml +6 -4
- data/Gemfile +2 -1
- data/README.md +2 -2
- data/lib/redisearch.rb +74 -23
- data/lib/redisearch/version.rb +1 -1
- data/redisearch-rb.gemspec +1 -1
- data/test/redisearch_test.rb +15 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1184cc3821b5bee90dcb18d41ad3b6ea9a93b750
|
4
|
+
data.tar.gz: 11ac50692f0cfc629e4283baa588e20cba18d854
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0e51193c7b3d7989f973472e5cdc4335f3ed428fa73c56ddbefa271023c053c85107639fc6f05bf0dee00820e4eb729cea3782ab7f0d62cb197d3587e7da624
|
7
|
+
data.tar.gz: ab05d37fe0469216d05dff6fa0223dd7530832b0a945226352a67a270a2e5239376111418793b7ccff8c2245b68916d46cc71fcba486c8a3f9b48c96d9b30904
|
data/.travis.yml
CHANGED
@@ -7,12 +7,14 @@ before_install:
|
|
7
7
|
- gem install bundler -v 1.14.6
|
8
8
|
- git clone --depth 10 https://github.com/antirez/redis.git
|
9
9
|
- cd redis
|
10
|
-
- git fetch
|
11
|
-
- git checkout
|
10
|
+
- git fetch && git fetch --tags
|
11
|
+
- git checkout 4.0.6
|
12
12
|
- make
|
13
13
|
- cd ..
|
14
14
|
- git clone --depth 1 https://github.com/RedisLabsModules/RediSearch.git
|
15
|
-
- cd RediSearch
|
15
|
+
- cd RediSearch
|
16
|
+
- git fetch && git fetch --tags
|
17
|
+
- git checkout v1.0.4
|
16
18
|
- make all
|
17
|
-
- ls -la *.so
|
18
19
|
- cd ..
|
20
|
+
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,8 +10,8 @@ http://redisearch.io/
|
|
10
10
|
|
11
11
|
First of all, you need to install RediSearch, if you haven't yet:
|
12
12
|
|
13
|
-
1. Install Redis 4.0.1 https://github.com/antirez/redis/releases/tag/4.0.1
|
14
|
-
2. Install RediSearch http://redisearch.io/Quick_Start/
|
13
|
+
1. Install Redis 4.0.1 or highger https://github.com/antirez/redis/releases/tag/4.0.1
|
14
|
+
2. Install RediSearch 1.0.4 or higher http://redisearch.io/Quick_Start/
|
15
15
|
3. Edit your `redis.conf` file and add a `loadmodule` directive to load the RediSearch module built in the step 2.
|
16
16
|
|
17
17
|
To install this gem, add this line to your application's Gemfile:
|
data/lib/redisearch.rb
CHANGED
@@ -12,12 +12,13 @@ class RediSearch
|
|
12
12
|
#
|
13
13
|
# { verbatim: true, withscores: true, withsortkey: false }
|
14
14
|
|
15
|
-
CREATE_OPTIONS_FLAGS = [:nooffsets, :nofreqs, :
|
16
|
-
ADD_OPTIONS_FLAGS = [:nosave, :replace]
|
15
|
+
CREATE_OPTIONS_FLAGS = [:nooffsets, :nofreqs, :nohl, :nofields]
|
16
|
+
ADD_OPTIONS_FLAGS = [:nosave, :replace, :partial]
|
17
17
|
SEARCH_OPTIONS_FLAGS = [:nocontent, :verbatim, :nostopwords, :withscores, :withsortkeys]
|
18
18
|
|
19
19
|
# Params options need an array with the values for the option
|
20
20
|
# { limit: ['0', '50'], sortby: ['year', 'desc'], return: ['2', 'title', 'year'] }
|
21
|
+
CREATE_OPTIONS_PARAMS = [:stopwords]
|
21
22
|
ADD_OPTIONS_PARAMS = [:language]
|
22
23
|
SEARCH_OPTIONS_PARAMS = [:filter, :return, :infields, :inkeys, :slop, :scorer, :sortby, :limit]
|
23
24
|
|
@@ -36,11 +37,11 @@ class RediSearch
|
|
36
37
|
|
37
38
|
# Create new index with the given `schema`
|
38
39
|
# @param [Array] schema
|
39
|
-
#
|
40
|
+
# @param [Hash] opts options
|
40
41
|
# Example:
|
41
42
|
#
|
42
43
|
# redisearch = RediSearch.new('my_idx')
|
43
|
-
# redisearch.create_idx(['title', 'TEXT', 'WEIGHT', '2.0', 'director', 'TEXT', 'WEIGHT', '1.0'])
|
44
|
+
# redisearch.create_idx(['title', 'TEXT', 'WEIGHT', '2.0', 'director', 'TEXT', 'WEIGHT', '1.0', 'year', 'NUMERIC', 'SORTABLE'])
|
44
45
|
#
|
45
46
|
# See http://redisearch.io/Commands/#ftcreate
|
46
47
|
#
|
@@ -87,22 +88,25 @@ class RediSearch
|
|
87
88
|
# See http://redisearch.io/Commands/#ftadd
|
88
89
|
# @return [String] "OK" on success
|
89
90
|
def add_docs(docs, opts = {})
|
90
|
-
|
91
|
+
docs.each { |doc_id, fields| call(ft_add(doc_id, fields, opts))}
|
91
92
|
end
|
92
93
|
|
93
94
|
# Search the index with the given `query`
|
94
95
|
# @param [String] query text query, see syntax here http://redisearch.io/Query_Syntax/
|
95
96
|
# @param [Hash] opts options for the query
|
96
97
|
#
|
97
|
-
|
98
|
+
# @return [Array] documents matching the query
|
98
99
|
def search(query, opts = {})
|
99
|
-
|
100
|
+
build_docs(call(ft_search(query, opts)), opts)
|
100
101
|
end
|
101
102
|
|
102
103
|
# Fetch a document by id
|
103
|
-
|
104
|
-
|
105
|
-
|
104
|
+
#
|
105
|
+
# @param [String] doc_id id assigned to the document
|
106
|
+
# @return [Hash] Hash containing document
|
107
|
+
def get_by_id(doc_id)
|
108
|
+
Hash[*call(ft_get(doc_id))]
|
109
|
+
.tap { |doc| doc['id'] = doc_id unless doc.empty? } || {}
|
106
110
|
end
|
107
111
|
|
108
112
|
# Return information and statistics on the index.
|
@@ -112,6 +116,36 @@ class RediSearch
|
|
112
116
|
Hash[*call(ft_info)]
|
113
117
|
end
|
114
118
|
|
119
|
+
# Deletes a document from the index
|
120
|
+
#
|
121
|
+
# See http://redisearch.io/Commands/#ftdel
|
122
|
+
#
|
123
|
+
# @param [String] doc_id id assigned to the document
|
124
|
+
# @return [int] 1 if the document was in the index, or 0 if not.
|
125
|
+
def delete_by_id(doc_id)
|
126
|
+
call(ft_del(doc_id))
|
127
|
+
end
|
128
|
+
|
129
|
+
# Deletes all documents returned by the query
|
130
|
+
#
|
131
|
+
# @param [String] query in the same format as used in `search`
|
132
|
+
# @param [Hash] opts options for the query, same as in `search`
|
133
|
+
# @return [int] count of documents deleted
|
134
|
+
def delete_by_query(query, opts = {})
|
135
|
+
call(ft_search(query, opts.merge(nocontent: true)))[1..-1].map do |doc_id|
|
136
|
+
call(ft_del(doc_id))
|
137
|
+
end.sum
|
138
|
+
end
|
139
|
+
|
140
|
+
# Execute arbitrary command. Only RediSearch commands are allowed
|
141
|
+
#
|
142
|
+
# @param [Array] command
|
143
|
+
# @return [mixed] The output returned by redis
|
144
|
+
def call(command)
|
145
|
+
raise ArgumentError.new("#{command&.first} is not a RediSearch command") unless valid_command?(command)
|
146
|
+
@redis.with_reconnect { @redis.call(command.flatten) }
|
147
|
+
end
|
148
|
+
|
115
149
|
private
|
116
150
|
|
117
151
|
def with_reconnect
|
@@ -122,10 +156,6 @@ class RediSearch
|
|
122
156
|
@redis.with_reconnect { @redis.multi { yield } }
|
123
157
|
end
|
124
158
|
|
125
|
-
def call(command)
|
126
|
-
@redis.with_reconnect { @redis.call(command) }
|
127
|
-
end
|
128
|
-
|
129
159
|
def add(doc_id, fields)
|
130
160
|
@redis.call(ft_add(doc_id, fields))
|
131
161
|
end
|
@@ -146,10 +176,26 @@ class RediSearch
|
|
146
176
|
['FT.ADD', @idx_name , doc_id, weight || DEFAULT_WEIGHT, *add_options(opts), 'FIELDS', *fields]
|
147
177
|
end
|
148
178
|
|
179
|
+
def ft_add_hash(doc_id, opts = {}, weight = nil)
|
180
|
+
['FT.ADDHASH', @idx_name , doc_id, weight || DEFAULT_WEIGHT, *add_options(opts)]
|
181
|
+
end
|
182
|
+
|
149
183
|
def ft_search(query, opts)
|
150
184
|
['FT.SEARCH', @idx_name, *query, *search_options(opts)].flatten
|
151
185
|
end
|
152
186
|
|
187
|
+
def ft_get(doc_id)
|
188
|
+
['FT.GET', @idx_name , doc_id]
|
189
|
+
end
|
190
|
+
|
191
|
+
def ft_mget(doc_ids)
|
192
|
+
['FT.MGET', @idx_name , *doc_ids]
|
193
|
+
end
|
194
|
+
|
195
|
+
def ft_del(doc_id)
|
196
|
+
['FT.DEL', @idx_name , doc_id]
|
197
|
+
end
|
198
|
+
|
153
199
|
def create_options(opts = {})
|
154
200
|
build_options(opts, CREATE_OPTIONS_FLAGS, [])
|
155
201
|
end
|
@@ -166,22 +212,27 @@ class RediSearch
|
|
166
212
|
flags_keys.map do |key|
|
167
213
|
key.to_s.upcase if opts[key]
|
168
214
|
end.compact +
|
169
|
-
|
170
|
-
|
171
|
-
|
215
|
+
params_keys.map do |key|
|
216
|
+
[key.to_s.upcase, *opts[key]] unless opts[key].nil?
|
217
|
+
end.compact
|
172
218
|
end
|
173
219
|
|
174
|
-
def
|
220
|
+
def build_docs(results, opts = {})
|
175
221
|
return {} if results.nil? || results[0] == 0
|
176
222
|
results.shift
|
177
|
-
|
178
|
-
|
179
|
-
|
223
|
+
score_offset = opts[:withscores] ? 1 : 0
|
224
|
+
content_offset = score_offset + 1
|
225
|
+
rows_per_doc = 1 + content_offset
|
226
|
+
nr_of_docs = results.size / rows_per_doc
|
180
227
|
(0..nr_of_docs-1).map do |n|
|
181
|
-
doc = Hash[*results[rows_per_doc * n +
|
182
|
-
doc['score'] = results[rows_per_doc * n +
|
228
|
+
doc = opts[:nocontent] ? {} : Hash[*results[rows_per_doc * n + content_offset]]
|
229
|
+
doc['score'] = results[rows_per_doc * n + score_offset] if opts[:withscores]
|
183
230
|
doc['id'] = results[rows_per_doc * n]
|
184
231
|
doc
|
185
232
|
end
|
186
233
|
end
|
234
|
+
|
235
|
+
def valid_command?(command)
|
236
|
+
command[0] =~ /^ft\./i
|
237
|
+
end
|
187
238
|
end
|
data/lib/redisearch/version.rb
CHANGED
data/redisearch-rb.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
RediSearch is a Redis powered search engine, developed by RedisLabs. http://redisearch.io/"
|
13
13
|
spec.homepage = "https://github.com/vruizext/redisearch-rb"
|
14
14
|
spec.license = "MIT"
|
15
|
-
|
15
|
+
spec.required_ruby_version = '> 2.4.0'
|
16
16
|
spec.files = `git ls-files`.split("\n")
|
17
17
|
spec.test_files = `git ls-files -- {test}/*`.split("\n")
|
18
18
|
end
|
data/test/redisearch_test.rb
CHANGED
@@ -10,6 +10,7 @@ class RediSearchTest < Minitest::Test
|
|
10
10
|
@redisearch_client = RediSearch.new('test_idx', @redis_client)
|
11
11
|
@schema = ['title', 'TEXT', 'WEIGHT', '2.0',
|
12
12
|
'director', 'TEXT', 'WEIGHT', '1.0',
|
13
|
+
'genre', 'TAG',
|
13
14
|
'year', 'NUMERIC', 'SORTABLE']
|
14
15
|
|
15
16
|
end
|
@@ -166,4 +167,18 @@ class RediSearchTest < Minitest::Test
|
|
166
167
|
assert_equal 1, info['max_doc_id'].to_i
|
167
168
|
assert_equal 5, info['num_terms'].to_i
|
168
169
|
end
|
170
|
+
|
171
|
+
def test_delete_by_id
|
172
|
+
assert(@redisearch_client.create_index(@schema))
|
173
|
+
docs = [['id_1', ['title', 'Lost in translation', 'director', 'Sofia Coppola', 'year', '2004']],
|
174
|
+
['id_2', ['title', 'Ex Machina', 'director', 'Alex Garland', 'year', '2014']],
|
175
|
+
['id_3', ['title', 'Terminator', 'director', 'James Cameron', 'year', '1984']],
|
176
|
+
['id_4', ['title', 'Blade Runner', 'director', 'Ridley Scott', 'year', '1982']]]
|
177
|
+
assert(@redisearch_client.add_docs(docs))
|
178
|
+
assert_equal(1, @redisearch_client.delete_by_id('id_1'))
|
179
|
+
assert_empty(@redisearch_client.search('@title:lost'))
|
180
|
+
assert(@redisearch_client.get_by_id('id_1').any?)
|
181
|
+
assert(@redis_client.del('id_1'))
|
182
|
+
assert(@redisearch_client.get_by_id('id_1').empty?)
|
183
|
+
end
|
169
184
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redisearch-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Ruiz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |-
|
14
14
|
A simple Ruby client library for RediSearch.
|
@@ -43,9 +43,9 @@ require_paths:
|
|
43
43
|
- lib
|
44
44
|
required_ruby_version: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
|
-
- - "
|
46
|
+
- - ">"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
48
|
+
version: 2.4.0
|
49
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
51
|
- - ">="
|