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

new(idx_name, redis_client = nil) click to toggle source

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_doc(doc_id, fields, opts = {}, weight = nil) click to toggle source

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_docs(docs, opts = {}) click to toggle source

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
add_hash(doc_id, opts = {}, weight = nil) click to toggle source

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
autocomplete_add(dict_name, content, score = 1.0, opts = {}) click to toggle source

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
autocomplete_del(dict_name, content) click to toggle source

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
autocomplete_get(dict_name, prefix, opts = {}) click to toggle source

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
autocomplete_len(dict_name) click to toggle source

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
call(command) click to toggle source

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_index(schema, opts = {}) click to toggle source

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
delete_by_id(doc_id, opts = {}) click to toggle source

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
delete_by_query(query, opts = {}) click to toggle source

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_index(opts = {}) click to toggle source

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
get_by_id(doc_id) click to toggle source

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
get_by_ids(doc_ids) click to toggle source

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
info() click to toggle source

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

Private Instance Methods

add(doc_id, fields) click to toggle source
# File lib/redisearch.rb, line 245
def add(doc_id, fields)
  @redis.call(ft_add(doc_id, fields))
end
build_docs(results, opts = {}) click to toggle source
# 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
flags_for_method(opts, method) click to toggle source
# 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
ft_add(doc_id, fields, opts = {}, weight = nil) click to toggle source
# 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
ft_addhash(doc_id, opts = {}, weight = nil) click to toggle source
# 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
ft_create(schema, opts) click to toggle source
# File lib/redisearch.rb, line 249
def ft_create(schema, opts)
  ['FT.CREATE', @idx_name , *serialize_options(opts, :create), 'SCHEMA', *schema]
end
ft_del(doc_id, opts) click to toggle source
# File lib/redisearch.rb, line 281
def ft_del(doc_id, opts)
  ['FT.DEL', @idx_name , doc_id, *serialize_options(opts, :del)]
end
ft_drop(opts) click to toggle source
# File lib/redisearch.rb, line 253
def ft_drop(opts)
  ['FT.DROP', @idx_name, *serialize_options(opts, :drop)]
end
ft_explain(query, opts) click to toggle source
# File lib/redisearch.rb, line 289
def ft_explain(query, opts)
  ['FT.EXPLAIN', @idx_name, *query, *serialize_options(opts, :search)].flatten
end
ft_get(doc_id) click to toggle source
# File lib/redisearch.rb, line 273
def ft_get(doc_id)
  ['FT.GET', @idx_name , doc_id]
end
ft_info() click to toggle source
# File lib/redisearch.rb, line 257
def ft_info
  ['FT.INFO', @idx_name]
end
ft_mget(doc_ids) click to toggle source
# File lib/redisearch.rb, line 277
def ft_mget(doc_ids)
  ['FT.MGET', @idx_name , *doc_ids]
end
ft_sugadd(dict_name, content, score, opts) click to toggle source
# 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
ft_sugdel(dict_name, content) click to toggle source
# File lib/redisearch.rb, line 297
def ft_sugdel(dict_name, content)
  ['FT.SUGDEL', dict_name , content]
end
ft_sugget(dict_name, prefix,opts) click to toggle source
# File lib/redisearch.rb, line 305
def ft_sugget(dict_name, prefix,opts)
  ['FT.SUGGET', dict_name , prefix, *serialize_options(opts, :sugget)]
end
ft_suglen(dict_name) click to toggle source
# File lib/redisearch.rb, line 301
def ft_suglen(dict_name)
  ['FT.SUGLEN', dict_name]
end
ft_tagvals(field_name) click to toggle source
# File lib/redisearch.rb, line 285
def ft_tagvals(field_name)
  ['FT.TAGVALS', @idx_name , field_name]
end
multi() { || ... } click to toggle source
# File lib/redisearch.rb, line 241
def multi
  @redis.with_reconnect { @redis.multi { yield } }
end
params_for_method(opts, method) click to toggle source
# 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
serialize_options(opts, method) click to toggle source
# File lib/redisearch.rb, line 309
def serialize_options(opts, method)
   [flags_for_method(opts, method), params_for_method(opts, method)].flatten.compact
end
valid_command?(command) click to toggle source
# 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
with_reconnect() { || ... } click to toggle source
# File lib/redisearch.rb, line 237
def with_reconnect
  @redis.with_reconnect { yield }
end