Redis OM for Node.js

repository·main·Indexed 23 days ago

https://github.com/redis/redis-om-node

An Object-Mapping library written in TypeScript that allows developers to model Redis data as JavaScript objects. It provides a fluent API for defining schemas, performing CRUD operations, and executing complex searches using Redis Stack modules such as RediSearch and RedisJSON. Supports both JSON and HASH data structures, geographic searches with Point types, and custom indexing configurations via SchemaOptions and AllFieldDefinition.

Tokens
22.2K
Snippets
31
Records
175
Agent score
78%

What's inside redis-om-node

  1. What is a Repository and how do I use it?

    main

    A Repository<T> is the primary interface for managing Entities in Redis. It provides methods for reading, writing, removing, and searching data based on a provided Schema.

    To use a repository, you typically create one using client.fetchRepository(schema). You can then manage your data lifecycle using fetch, save, and remove.

  2. Use the Where class for search queries

    main
    The Where class is an abstract base class used to construct query criteria for the Search API. It serves as the foundation for all field-specific query expressions (via WhereField). When used within a search operation, the Where object is responsible for defining the filtering logic that will be translated into a RediSearch query string.
  3. Understanding missing entities and null values

    main

    Because Redis (specifically Hashes) does not differentiate between a missing field and a null value, Redis OM has specific behaviors:

    1. Fetching non-existent entities: If you .fetch() an ID that does not exist, Redis OM returns an object containing that ID (via EntityId), but all other properties will be undefined.
    2. Deleting an entity via .save(): If you fetch an entity, delete all its properties, and then call .save(), Redis OM will remove the entity from Redis entirely.

    Note: If you fetch a non-existent entity, the object returned will look like this:

    const album = await albumRepository.fetch('TOTALLY_BOGUS')
    // album[EntityId] is 'TOTALLY_BOGUS'
    // album.artist is undefined
  4. Use WhereField to build entity filters

    main

    The WhereField<T> class is the abstract base class used for filtering entities in Redis OM. When you use the where() method on a search collection, it returns a subclass of WhereField corresponding to the field you are querying. This allows you to chain comparison methods to build complex queries.

    WhereField supports several fluent accessors to improve code readability:

    • is: Syntactic sugar to return the current instance.
    • does: Syntactic sugar to return the current instance.
    • not: Negates the current query condition. Calling not multiple times will negate the negation (e.g., field.is(val).not().not() is equivalent to field.is(val)).
  5. Handle errors with RedisOmError

    main

    The RedisOmError class is the base error type for all errors thrown by Redis OM for Node.js. It extends the standard JavaScript Error class. When catching errors in your application, you can check if an error is an instance of RedisOmError to identify issues originating from the library.

    RedisOmError has several specialized subclasses for specific error scenarios:

    • InvalidInput: Thrown when input data does not meet expected formats.
    • InvalidSchema: Thrown when there are issues with the defined entity schema.
    • InvalidValue: Thrown when a value is invalid for its type or constraints.
    • PointOutOfRange: Thrown when a numeric or spatial value is outside allowed bounds.
    • SearchError: Thrown when an error occurs during a search operation.
  6. Define Entities and Schemas in Redis OM

    main

    Redis OM uses Entities (JavaScript objects) and Schemas to map data to Redis.

    A Schema defines the fields of an entity, their types, and how they are stored. The first argument to the Schema constructor is the Schema name, which acts as the key name prefix for all entities of that type in Redis.

    Supported Field Types

    • string: Exact match only. Best for discrete data like IDs or status.
    • text: Enables full-text search (supports stemming and stop words). Best for human-readable content.
    • number: Numeric values.
    • boolean: Boolean values.
    • string[]: An array of strings.
    • number[]: An array of numbers (Note: only supported with JSON data structure).
    • date: A JavaScript Date, an ISO 8601 string, or a UNIX epoch timestamp in seconds.
    • point: A geographic point expressed as { longitude: number, latitude: number }.
    import { Schema } from 'redis-om'
    
    const albumSchema = new Schema('album', {
      artist: { type: 'string' },
      title: { type: 'text' },
      year: { type: 'number' },
      genres: { type: 'string[]' },
      songDurations: { type: 'number[]' },
      outOfPublication: { type: 'boolean' }
    })
  7. Understand the Entity data structure

    main

    An Entity represents the object returned from a Repository. It combines user-defined data (EntityData) with internal metadata (EntityInternal).

    • EntityData: A free-form object where values (EntityDataValue) can be string, number, boolean, Date, Point, null, undefined, or an array of these types.
    • EntityInternal: Contains system-managed properties:
      • EntityId: The unique ID of the entity (accessed via the EntityId Symbol).
      • EntityKeyName: The Redis key under which the entity is stored (accessed via the EntityKeyName Symbol).
  8. Use RawSearch to execute RediSearch queries

    main

    RawSearch<T> is the entry point for performing raw RediSearch queries against Redis OM. This allows you to bypass the high-level abstraction and use raw RediSearch query syntax directly.

    Requirements:

    • RediSearch must be installed on your Redis instance.
    • RedisJSON is optionally required depending on your entity structure.

    T is a type parameter representing the Entity being searched, which defaults to Record<string, any> if not specified.

  9. Handle InvalidInput errors

    main

    The InvalidInput class is a specific type of RedisOmError used when the data provided to Redis OM does not match the expected format or schema. It is a base class for several more specific error types, including:

    • NullJsonInput: Occurs when a null value is provided where JSON is expected.
    • InvalidJsonInput: Occurs when the input is not valid JSON.
    • InvalidHashInput: Occurs when the input is not a valid Hash.
    • NestedHashInput: Occurs when a nested Hash structure is invalid.
    • ArrayHashInput: Occurs when an array of Hashes is invalid.

    When catching these errors, you can access the message to understand the validation failure and the cause to see the underlying error that triggered it.

  10. Choose between JSON and Hash data structures

    main

    By default, Redis OM stores entities as JSON documents using RedisJSON. You can explicitly set the dataStructure in the schema options.

    • JSON: Supports nested trees and arrays (e.g., number[]). Use this for complex, hierarchical data.
    • HASH: Stores data as a flat structure. Fields contain values. Note: Arrays like number[] are not supported in Hashes and will cause an error.

    To switch to Hashes, pass { dataStructure: 'HASH' } as the third argument to the Schema constructor.

    // Using JSON (Default)
    const albumSchema = new Schema('album', {
      artist: { type: 'string' }
    }, {
      dataStructure: 'JSON'
    })
    
    // Using HASH
    const albumSchema = new Schema('album', {
      artist: { type: 'string' }
    }, {
      dataStructure: 'HASH'
    })
  11. Use different field types in SchemaDefinition

    main

    A SchemaDefinition is a mapping of entity keys to FieldDefinitions. Supported field types include:

    • "boolean": BooleanFieldDefinition
    • "date": DateFieldDefinition (supports sortable)
    • "number": NumberFieldDefinition (supports sortable)
    • "number[]": NumberArrayFieldDefinition (supports sortable)
    • "point": PointFieldDefinition (for geographic coordinates)
    • "string": StringFieldDefinition (supports sortable, caseSensitive, normalized, separator)
    • "string[]": StringArrayFieldDefinition (supports sortable, caseSensitive, normalized, separator)
    • "text": TextFieldDefinition (supports sortable, normalized, matcher, stemming, weight)

    Each definition must include a type and common properties like indexed, path, or field.

  12. Perform logical AND and OR queries

    main

    You can combine query conditions using logical operators:

    • AND:
      • Use where(field) or and(field) to filter on a specific field. Multiple calls to where() are treated as logical AND.
      • Use and(subSearchFn) to set up a nested search as a logical AND.
    • OR:
      • Use or(field) to filter on a field as a logical OR.
      • Use or(subSearchFn) to set up a nested search as a logical OR.