class RediSearch
Ruby client for RediSearch
module redisearch.io/
Constants
- DEFAULT_WEIGHT
- OPTIONS_FLAGS
Supported options Flags options can be only true or false,
{ verbatim: true, withscores: true, withsortkey: false }
- OPTIONS_PARAMS
Params options need an array with the values for the option
{ limit: ['0', '50'], sortby: ['year', 'desc'], return: ['2', 'title', 'year'] }
- VERSION
Public Class Methods
Create RediSearch
client instance
@param [String] idx_name name of the index @param [Redis] redis_client Redis instance If no `redis_client` is given, `RediSearch` tries to connect to the default redis url i.e. redis://127.0.0.1:6379
@return [RediSearch] a new client instance
# File lib/redisearch.rb, line 44 def initialize(idx_name, redis_client = nil) @idx_name = idx_name @redis = redis_client || Redis.new end
Public Instance Methods
Add a single doc to the index, with the given `doc_id` and `fields`
@param [String] doc_id id assigned to the document @param [Array] fields name-value pairs to be indexed @param [Float] weight asigned by the user to the document @param [Hash] opts optional parameters Example:
redisearch = RediSearch.new('my_idx') redisearch.add_doc('id_1', ['title', 'Lost in translation', 'director', 'Sofia Coppola'])
See redisearch.io/Commands/#ftadd @return [String] “OK” on success
# File lib/redisearch.rb, line 85 def add_doc(doc_id, fields, opts = {}, weight = nil) call(ft_add(doc_id, fields, opts, weight)) end
Add a set of docs to the index. Uses redis `multi` to make a single bulk insert.
@param [Array] docs array of tuples doc_id-fields e.g. [[`id_1`, [fields_doc_1]], [`id_2`, [fields_doc_2]]]
Example:
redisearch = RediSearch.new('my_idx') docs = [['id_1', ['title', 'Lost in translation', 'director', 'Sofia Coppola'], 0.75], ['id_2', ['title', 'Ex Machina', 'director', 'Alex Garland'], 0.95] redisearch.add_docs(docs)
See redisearch.io/Commands/#ftadd @return [String] “OK” on success
# File lib/redisearch.rb, line 102 def add_docs(docs, opts = {}) docs.map { |doc_id, fields, weight| call(ft_add(doc_id, fields, opts, weight))} end
Adds a document to the index from an existing HASH key `doc_id` in Redis.
@param [String] doc_id HASH key holding the fields that need to be indexed @param [Hash] opts optional parameters @param [Float]weight asigned by the user to the document Example:
redisearch = RediSearch.new('my_idx') redisearch.add_hash('id_1', { weight: true })
See redisearch.io/Commands/#ftadd @return [String] “OK” on success
# File lib/redisearch.rb, line 118 def add_hash(doc_id, opts = {}, weight = nil) call(ft_addhash(doc_id, opts, weight)) end
Adds a string to an auto-complete suggestion dictionary.
See oss.redislabs.com/redisearch/Commands/#ftsugadd
@param [String] dict_name the key used to store the dictionary @param [String] content the string that is going to be indexed @param [Hash] opts optional parameters @return [int] current size of the dictionary
# File lib/redisearch.rb, line 186 def autocomplete_add(dict_name, content, score = 1.0, opts = {}) call(ft_sugadd(dict_name, content, score, opts)) end
Deletes a string from an auto-complete suggestion dictionary.
See oss.redislabs.com/redisearch/Commands/#ftsugdel
@param [String] dict_name the key used to store the dictionary @param [String] content the string that is going to be deleted @param [Hash] opts optional parameters @return [int] 1 if the string was found and deleted, 0 otherwise
# File lib/redisearch.rb, line 211 def autocomplete_del(dict_name, content) call(ft_sugdel(dict_name, content)) end
Gets completion suggestions for a prefix.
See oss.redislabs.com/redisearch/Commands/#ftsugadd
@param [String] dict_name the key used to store the dictionary @param [String] prefix the prefix to search / complete @param [Hash] opts optional parameters @return [Array] a list of the top suggestions matching the prefix, optionally with score after each entry
# File lib/redisearch.rb, line 199 def autocomplete_get(dict_name, prefix, opts = {}) call(ft_sugget(dict_name, prefix, opts)) end
Gets the current size of an auto-complete suggestion dictionary.
See oss.redislabs.com/redisearch/Commands/#ftsugdel
@param [String] dict_name the key used to store the dictionary @return [int] current size of the dictionary
# File lib/redisearch.rb, line 221 def autocomplete_len(dict_name) call(ft_suglen(dict_name)) end
Execute arbitrary command in redisearch index Only RediSearch
commands are allowed
@param [Array] command @return [mixed] The output returned by redis
# File lib/redisearch.rb, line 230 def call(command) raise ArgumentError.new("unknown/unsupported command '#{command.first}'") unless valid_command?(command.first) @redis.with_reconnect { @redis.call(command.flatten) } end
Create new index with the given `schema` @param [Array] schema @param [Hash] opts options Example:
redisearch = RediSearch.new('my_idx') redisearch.create_idx(['title', 'TEXT', 'WEIGHT', '2.0', 'director', 'TEXT', 'WEIGHT', '1.0', 'year', 'NUMERIC', 'SORTABLE'])
See redisearch.io/Commands/#ftcreate
@return [String] “OK” on success
# File lib/redisearch.rb, line 60 def create_index(schema, opts = {}) call(ft_create(schema, opts)) end
Deletes a document from the index
See redisearch.io/Commands/#ftdel
@param [String] doc_id id assigned to the document @return [int] 1 if the document was in the index, or 0 if not.
# File lib/redisearch.rb, line 163 def delete_by_id(doc_id, opts = {}) call(ft_del(doc_id, opts)) end
Deletes all documents matching the query
@param [String] query in the same format as used in `search` @param [Hash] opts options for the query, same as in `search` @return [int] count of documents deleted
# File lib/redisearch.rb, line 172 def delete_by_query(query, opts = {}) call(ft_search(query, opts.merge(nocontent: true)))[1..-1].map do |doc_id| call(ft_del(doc_id, opts)) end.sum end
Drop all the keys in the current index
See redisearch.io/Commands/#ftdrop @return [String] “OK” on success
# File lib/redisearch.rb, line 68 def drop_index(opts = {}) call(ft_drop(opts)) end
Fetch a document by id
@param [String] doc_id id assigned to the document @return [Hash] Hash containing document
# File lib/redisearch.rb, line 145 def get_by_id(doc_id) Hash[*call(ft_get(doc_id))] .tap { |doc| doc['id'] = doc_id unless doc.empty? } || {} end
Fetch the contents of multiple documents
@param [Array] doc_ids ids assigned to the document @return [Array] documents found for the ids given
# File lib/redisearch.rb, line 135 def get_by_ids(doc_ids) call(ft_mget(doc_ids)).map.with_index do |doc, i| { 'id' => doc_ids[i] }.merge(Hash[*doc]) unless doc.empty? end.compact end
Return information and statistics on the index. @return [Hash] info returned by Redis key-value pairs
# File lib/redisearch.rb, line 153 def info Hash[*call(ft_info)] end
Search the index with the given `query` @param [String] query text query, see syntax here redisearch.io/Query_Syntax/ @param [Hash] opts options for the query
@return [Array] documents matching the query
# File lib/redisearch.rb, line 127 def search(query, opts = {}) build_docs(call(ft_search(query, opts)), opts) end
Private Instance Methods
# File lib/redisearch.rb, line 245 def add(doc_id, fields) @redis.call(ft_add(doc_id, fields)) end
# File lib/redisearch.rb, line 325 def build_docs(results, opts = {}) return [] if results.nil? || results[0] == 0 results.shift score_offset = opts[:withscores] ? 1 : 0 content_offset = opts[:nocontent] ? 0 : 1 rows_per_doc = 1 + content_offset + score_offset nr_of_docs = results.size / rows_per_doc (0..nr_of_docs-1).map do |n| doc = opts[:nocontent] ? {} : Hash[*results[rows_per_doc * n + content_offset + score_offset]] doc['score'] = results[rows_per_doc * n + score_offset] if opts[:withscores] doc['id'] = results[rows_per_doc * n] doc end end
# File lib/redisearch.rb, line 313 def flags_for_method(opts, method) OPTIONS_FLAGS[method].to_a.map do |key| key.to_s.upcase if opts[key] end.compact end
# File lib/redisearch.rb, line 261 def ft_add(doc_id, fields, opts = {}, weight = nil) ['FT.ADD', @idx_name , doc_id, weight || DEFAULT_WEIGHT, *serialize_options(opts, :add), 'FIELDS', *fields] end
# File lib/redisearch.rb, line 265 def ft_addhash(doc_id, opts = {}, weight = nil) ['FT.ADDHASH', @idx_name , doc_id, weight || DEFAULT_WEIGHT, *serialize_options(opts, :add)] end
# File lib/redisearch.rb, line 249 def ft_create(schema, opts) ['FT.CREATE', @idx_name , *serialize_options(opts, :create), 'SCHEMA', *schema] end
# File lib/redisearch.rb, line 281 def ft_del(doc_id, opts) ['FT.DEL', @idx_name , doc_id, *serialize_options(opts, :del)] end
# File lib/redisearch.rb, line 253 def ft_drop(opts) ['FT.DROP', @idx_name, *serialize_options(opts, :drop)] end
# File lib/redisearch.rb, line 289 def ft_explain(query, opts) ['FT.EXPLAIN', @idx_name, *query, *serialize_options(opts, :search)].flatten end
# File lib/redisearch.rb, line 273 def ft_get(doc_id) ['FT.GET', @idx_name , doc_id] end
# File lib/redisearch.rb, line 257 def ft_info ['FT.INFO', @idx_name] end
# File lib/redisearch.rb, line 277 def ft_mget(doc_ids) ['FT.MGET', @idx_name , *doc_ids] end
# File lib/redisearch.rb, line 269 def ft_search(query, opts) ['FT.SEARCH', @idx_name, *query, *serialize_options(opts, :search)].flatten end
# File lib/redisearch.rb, line 293 def ft_sugadd(dict_name, content, score, opts) ['FT.SUGADD', dict_name , content, score, *serialize_options(opts, :sugadd)] end
# File lib/redisearch.rb, line 297 def ft_sugdel(dict_name, content) ['FT.SUGDEL', dict_name , content] end
# File lib/redisearch.rb, line 305 def ft_sugget(dict_name, prefix,opts) ['FT.SUGGET', dict_name , prefix, *serialize_options(opts, :sugget)] end
# File lib/redisearch.rb, line 301 def ft_suglen(dict_name) ['FT.SUGLEN', dict_name] end
# File lib/redisearch.rb, line 285 def ft_tagvals(field_name) ['FT.TAGVALS', @idx_name , field_name] end
# File lib/redisearch.rb, line 241 def multi @redis.with_reconnect { @redis.multi { yield } } end
# File lib/redisearch.rb, line 319 def params_for_method(opts, method) OPTIONS_PARAMS[method].to_a.map do |key| [key.to_s.upcase, *opts[key]] unless opts[key].nil? end.compact end
# File lib/redisearch.rb, line 309 def serialize_options(opts, method) [flags_for_method(opts, method), params_for_method(opts, method)].flatten.compact end
# File lib/redisearch.rb, line 340 def valid_command?(command) %w(FT.CREATE FT.ADD FT.ADDHASH FT.SEARCH FT.DEL FT.DROP FT.GET FT.MGET FT.SUGADD FT.SUGGET FT.SUGDEL FT.SUGLEN FT.SYNADD FT.SYNUPDATE FT.SYNDUMP FT.INFO FT.AGGREGATE FT.EXPLAIN FT.TAGVALS).include?(command) end
# File lib/redisearch.rb, line 237 def with_reconnect @redis.with_reconnect { yield } end