Redis.Search (Redis v0.7.1)

Copy Markdown View Source

High-level search API for Redis, inspired by Meilisearch.

Wraps the RediSearch FT.* commands with an Elixir-friendly interface: keyword-based schemas, map-based documents, Elixir filter expressions instead of raw query strings, and parsed result structs.

For raw command access, see Redis.Commands.Search.

Quick Start

# Create an index
Redis.Search.create_index(conn, "movies",
  prefix: "movie:",
  fields: [
    title: :text,
    year: {:numeric, sortable: true},
    genres: :tag
  ]
)

# Add documents as maps
Redis.Search.add(conn, "movies", "movie:1", %{
  title: "The Dark Knight",
  year: 2008,
  genres: "action,thriller"
})

# Search with Elixir filters
Redis.Search.find(conn, "movies", "dark knight",
  where: [year: {:gt, 2000}, genres: "action"],
  sort: {:year, :desc},
  limit: 10
)
#=> {:ok, %Redis.Search.Result{total: 1, results: [%{id: "movie:1", ...}]}}

Filter Syntax

The :where option accepts a keyword list compiled to RediSearch query syntax:

  • field: "value" -- text match (@field:value)
  • field: {:match, "hello world"} -- phrase match (@field:(hello world))
  • field: {:gt, n} -- greater than (@field:[(n +inf])
  • field: {:gte, n} -- greater than or equal (@field:[n +inf])
  • field: {:lt, n} -- less than (@field:[-inf (n])
  • field: {:lte, n} -- less than or equal (@field:[-inf n])
  • field: {:between, min, max} -- range (@field:[min max])
  • field: {:tag, "val"} -- exact tag (@field:{val})
  • field: {:any, ["a", "b"]} -- tag OR (@field:{a|b})

Options

  • :where -- filter keyword list (see above)
  • :sort -- {field, :asc | :desc}

  • :limit -- max results (integer) or {offset, count}
  • :return -- list of fields to return
  • :nocontent -- return only IDs (boolean)
  • :dialect -- RediSearch query dialect version
  • :coerce -- auto-coerce numeric strings (default: true)

Summary

Functions

Adds a document to an index.

Adds multiple documents via pipeline.

Runs an aggregation query.

Creates a search index.

Drops a search index. Pass dd: true to also delete indexed documents.

Searches an index with Elixir-friendly filters.

Returns index info as a map.

Functions

add(conn, index, key, doc, opts \\ [])

Adds a document to an index.

Auto-detects hash vs JSON based on the index type. Pass :on to override if the index hasn't been inspected yet.

Redis.Search.add(conn, "movies", "movie:1", %{
  title: "Inception",
  year: 2010,
  genres: "sci-fi,thriller"
})

add_many(conn, index, docs, opts \\ [])

Adds multiple documents via pipeline.

Redis.Search.add_many(conn, "movies", [
  {"movie:1", %{title: "Inception", year: 2010}},
  {"movie:2", %{title: "Interstellar", year: 2014}}
])

aggregate(conn, index, opts \\ [])

Runs an aggregation query.

Redis.Search.aggregate(conn, "movies",
  group_by: :genres,
  reduce: [count: "total"],
  sort: {:total, :desc},
  limit: 10
)

# Multiple reducers
Redis.Search.aggregate(conn, "movies",
  group_by: [:city],
  reduce: [
    count: "total",
    avg: {:score, "avg_score"}
  ]
)

Reducers

  • count: "alias" -- COUNT
  • sum: {:field, "alias"} -- SUM
  • avg: {:field, "alias"} -- AVG
  • min: {:field, "alias"} -- MIN
  • max: {:field, "alias"} -- MAX

create_index(conn, index, opts)

Creates a search index.

Fields are specified as a keyword list:

Redis.Search.create_index(conn, "idx", fields: [name: :text, age: :numeric])
Redis.Search.create_index(conn, "idx",
  on: :json,
  prefix: "doc:",
  fields: [
    title: :text,
    score: {:numeric, sortable: true},
    tags: :tag
  ]
)

Options

  • :fields (required) -- keyword list of {name, type} or {name, {type, opts...}}
  • :on -- :hash (default) or :json
  • :prefix -- key prefix string or list
  • :stopwords -- list of stopwords or 0 for none
  • :language -- default language

drop_index(conn, index, opts \\ [])

Drops a search index. Pass dd: true to also delete indexed documents.

find(conn, index, query \\ "*", opts \\ [])

Searches an index with Elixir-friendly filters.

# Simple full-text search
Redis.Search.find(conn, "movies", "dark knight")

# With filters
Redis.Search.find(conn, "movies", "batman",
  where: [year: {:gt, 2000}, genres: {:tag, "action"}],
  sort: {:year, :desc},
  limit: 10,
  return: [:title, :year]
)

See module docs for the full filter syntax.

index_info(conn, index)

Returns index info as a map.