Golang client for redislabs' ReJSON module with support for multilple redis clients (redigo, go-redis)

Go-ReJSON - a golang client for ReJSON (a JSON data type for Redis)

Go-ReJSON is a Go client for ReJSON Redis Module.

Go Reference test code-analysis codecov Go Report Card GitHub release

ReJSON is a Redis module that implements ECMA-404 The JSON Data Interchange Standard as a native data type. It allows storing, updating and fetching JSON values from Redis keys (documents).

Primary features of ReJSON Module:

* Full support of the JSON standard
* JSONPath-like syntax for selecting element inside documents
* Documents are stored as binary data in a tree structure, allowing fast access to sub-elements
* Typed atomic operations for all JSON values types

Each and every feature of ReJSON Module is fully incorporated in the project.

Enjoy ReJSON with the type-safe Redis client, Go-Redis/Redis or use the print-like Redis-api client GoModule/Redigo. Go-ReJSON supports both the clients. Use any of the above two client you want, Go-ReJSON helps you out with all its features and functionalities in a more generic and standard way.

Support for mediocregopher/radix and other Redis clients is in our RoadMap. Any contributions on the support for other clients is hearty welcome.

Installation

go get github.com/nitishm/go-rejson

Example usage

package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"

	"github.com/nitishm/go-rejson/v4"
	goredis "github.com/go-redis/redis/v8"
	"github.com/gomodule/redigo/redis"
)

// Name - student name
type Name struct {
	First  string `json:"first,omitempty"`
	Middle string `json:"middle,omitempty"`
	Last   string `json:"last,omitempty"`
}

// Student - student object
type Student struct {
	Name Name `json:"name,omitempty"`
	Rank int  `json:"rank,omitempty"`
}

func Example_JSONSet(rh *rejson.Handler) {

	student := Student{
		Name: Name{
			"Mark",
			"S",
			"Pronto",
		},
		Rank: 1,
	}
	res, err := rh.JSONSet("student", ".", student)
	if err != nil {
		log.Fatalf("Failed to JSONSet")
		return
	}

	if res.(string) == "OK" {
		fmt.Printf("Success: %s\n", res)
	} else {
		fmt.Println("Failed to Set: ")
	}

	studentJSON, err := redis.Bytes(rh.JSONGet("student", "."))
	if err != nil {
		log.Fatalf("Failed to JSONGet")
		return
	}

	readStudent := Student{}
	err = json.Unmarshal(studentJSON, &readStudent)
	if err != nil {
		log.Fatalf("Failed to JSON Unmarshal")
		return
	}

	fmt.Printf("Student read from redis : %#v\n", readStudent)
}

func main() {
	var addr = flag.String("Server", "localhost:6379", "Redis server address")

	rh := rejson.NewReJSONHandler()
	flag.Parse()

	// Redigo Client
	conn, err := redis.Dial("tcp", *addr)
	if err != nil {
		log.Fatalf("Failed to connect to redis-server @ %s", *addr)
	}
	defer func() {
		_, err = conn.Do("FLUSHALL")
		err = conn.Close()
		if err != nil {
			log.Fatalf("Failed to communicate to redis-server @ %v", err)
		}
	}()
	rh.SetRedigoClient(conn)
	fmt.Println("Executing Example_JSONSET for Redigo Client")
	Example_JSONSet(rh)

	// GoRedis Client
	cli := goredis.NewClient(&goredis.Options{Addr: *addr})
	defer func() {
		if err := cli.FlushAll().Err(); err != nil {
			log.Fatalf("goredis - failed to flush: %v", err)
		}
		if err := cli.Close(); err != nil {
			log.Fatalf("goredis - failed to communicate to redis-server: %v", err)
		}
	}()
	rh.SetGoRedisClient(cli)
	fmt.Println("\nExecuting Example_JSONSET for Redigo Client")
	Example_JSONSet(rh)
}
Owner
Nitish Malhotra
Senior Software Engineer @microsoft C+AI University of Pennsylvania Alum Past:Oracle/CSPi/HERE technologies Focus: Golang, Kubernetes, Istio, DevOps
Nitish Malhotra
Comments
  • Set Go Redis V7 Client Problem

    Set Go Redis V7 Client Problem

    HI, I want so set the goredis/v7 to use rejson, but when I set the client,

    the error shows:

    Cannot use (type *"github.com/go-redis/redis/v7".Client) as type *"github.com/go-redis/redis".Client 
    

    looks like the lib only accept "github.com/go-redis/redis" (v6),

    can fix the problem? thanks..

  • Support go-redis as the redis client

    Support go-redis as the redis client

    The goal of this feature is to add support for more redis clients like go-rejson, gosexy/redis,etc., rather than have it tightly coupled with redigo, which is how it is currently written to work.

    The go-rejson library relies on the redigo.Conn object, which is passed in as a dependencies to each of the exported methods, which in turn rely on the Do() method of the redigo.Conn object.

    See JSONSet - https://github.com/nitishm/go-rejson/blob/master/rejson.go#L273-L279

    The feature/enhancement should keep the library backwards compatible (if possible) by abstracting away the conn.Do() method, in a way that it works with all supported client libraries.

  • Fix encoding to work with Cyrillic and Portuguese accentuation

    Fix encoding to work with Cyrillic and Portuguese accentuation

    Context

    As we know in the issue #56 some characters when read from the database are not being processing as valid UTF-8 Characters. So this fixes it to handle the full length of the data representation for them

    Closes #56

  • cannot use cli (type *

    cannot use cli (type *"github.com/go-redis/redis".Client) as type *"github.com/nitishm/go-rejson/vendor/github.com/go-redis/redis".Client in argument to rh.SetGoRedisClientgo

    Error: cannot use cli (type *"github.com/go-redis/redis".Client) as type *"github.com/nitishm/go-rejson/vendor/github.com/go-redis/redis".Client in argument to rh.SetGoRedisClientgo

    When trying to run example code on like 97:

    rh.SetGoRedisClient(cli)
    
  • Add gometalinter to travis ci #20

    Add gometalinter to travis ci #20

    #20 I added in gometalinter to travisci in this repo. Gometalinter uses the following lint method.

    gometalinter --concurrency=4 --enable-gc --deadline=300s --disable-all 
    --enable=deadcode
    --enable=errcheck
    --enable=goconst
    --enable=gofmt 
    --enable=goimports
    --enable=golint
    --exclude=.pb.go
    --enable=gotype
    --enable=ineffassign
    --enable=interfacer
    --enable=lll --line-length=120 
    --enable=misspell 
    --enable=structcheck 
    --enable=unconvert 
    --enable=unused 
    --enable=varcheck 
    --enable=vet 
    --enable=maligned 
    --vendor ./...
    

    https://github.com/alecthomas/gometalinter#supported-linters

    I would like to know whether you want to use supported linters else.

  • Compatibility with  rejson:latest 2.0.6

    Compatibility with rejson:latest 2.0.6

    Problem

    • Problems with the JSON.DEBUG
    • For some reason redigo is returning JSON.TYPE string as a Byte array at version >2.0.6 image

    image

    Solution

    • JSON.DEBUG instability may be a reason to disable their tests for now or make it more dynamic for more expected values
    • For the redigo JSON.TYPE a type handling could solve the issue
  • Support for various clients

    Support for various clients

    Moving forward on the proposed work in the issue https://github.com/nitishm/go-rejson/issues/27#issuecomment-453861407

    The project now, is all set to implement the ReJSON commands for various clients.

    Checklist to implement gomodule/redigo client:

    • [x] Interface setup and other stuffs to be used during client implementation
    • [x] ~~Abstracting options for other commands like JSON.ARRINDEX and JSON.ARRPOP, as done forJSON.GET and JSON.SET~~

    Edited: I think their abstraction is not much required, they are very well maintained rigthnow

    • [x] Adding proper examples and details in comments so that the godoc of the repo will be improved
    • [x] Implementation of commands in gomodule/redigo
    • [x] Adding proper test cases for clients

    Similarly, for other clients:

    • [x] gomodule/redigo
    • [x] go-redis/redis

    Support for mediocregopher/radix is moved to the future roadmap

  • `redis: client is closed` only with go-redis/v8 + go-rejson/v4

    `redis: client is closed` only with go-redis/v8 + go-rejson/v4

    Describe the bug I get an error trying to access redis either via go-redis or go-rejoin, once I add go-rejson to my code.

    To Reproduce Basically close to the default example. Accessing either the database via either redis.Client or rejson.Handler will cause the redis: client is closed error. Removing rejson.Handler from my setup to look like the second code block fixes my issue (which is not ideal, since I'd like to use go-rejson).

    // Causes database to just not be accessible
    func SetupDatabase() (*redis.Client, *rejson.Handler) {
    	rh := rejson.NewReJSONHandler()
    
    	client := redis.NewClient(&redis.Options{
    		Addr:     redisAddr,
    		Password: redisPass,
    	})
    	defer func() {
    		if err := client.FlushAll(ctx).Err(); err != nil {
    			log.Fatalf("goredis - failed to flush: %v", err)
    		} else {
    			log.Printf("goredis - flushed")
    		}
    		if err := client.Close(); err != nil {
    			log.Fatalf("goredis - failed to communicate to redis-server: %v", err)
    		}
    	}()
    
    	rh.SetGoRedisClient(client)
    	return client, rh
    }
    
    // Works fine
    func SetupDatabase() (*redis.Client, *rejson.Handler) {
    	client := redis.NewClient(&redis.Options{
    		Addr:     redisAddr,
    		Password: redisPass,
    	})
    	return client
    }
    

    Expected behavior It works fine

    Desktop (please complete the following information):

    • OS: Arch
    • Redis: go-rejson v4
    • Redis server: v6.2.5

    Additional context It looks like client.PoolStats().Misses is 1 after doing the .FulshAll. Removing the .FlushAll does not fix anything, but it does change Misses to 0. client.PoolStats().TotalConns is always 0 for whatever reason.

    I'm running redis-server 6.2.5.

  • Remove direct dependency of clients for obtaining connection

    Remove direct dependency of clients for obtaining connection

    go-redis provides 4 different types of protocols to connect to Redis

    • Normal standalone: https://redis.uptrace.dev/guide/server.html#connecting-to-redis-server
    • Cluster: https://redis.uptrace.dev/guide/cluster.html
    • Ring: https://redis.uptrace.dev/guide/ring.html

    Similarly, Redigo provides a single method:

    • Conn: https://pkg.go.dev/github.com/gomodule/redigo/redis#Conn

    And as we only use Do method of both the clients. Hence, in order to support these different types of connections in each client, abstracting the required method is the only feasible option

    Originally posted by @Shivam010 in https://github.com/nitishm/go-rejson/issues/62#issuecomment-1042046636

  • Set Go Redis V8 Client Problem

    Set Go Redis V8 Client Problem

    Hi,

    I wanted to report incompatibilities with v8 of go-redis. According to go-redis documentation, v8 is the latest recommended version.

    Very similar to the issue concerning upgrading from go-redis v6 to v7.

  • Installation step does not work

    Installation step does not work

    Describe the bug go get github.com/nitishm/go-rejson throws the following error

    "package github.com/go-redis/redis/v7: cannot find package "github.com/go-redis/redis/v7" in any of"

    To Reproduce go get github.com/nitishm/go-rejson

    Expected behavior Package should install properly

    Screenshots If applicable, add screenshots to help explain your problem.

    Desktop (please complete the following information): macOS 10.15.5

  • Mocking JSONSet

    Mocking JSONSet

    Hi - I'm using redismock for unit testing. I am not able to get the JSONSet mocked. Tried ExpectHMSet, ExpectSet etc. but no dice. Has anyone done this?

  • jsonGet return multiple paths (fields) for a given key

    jsonGet return multiple paths (fields) for a given key

    Not entirely sure if this is a feature request, or my ignorance?

    In the native redis-cli this command works: JSON.GET somekey path1 path2 path3 In rejson this command works: jsonGet(somekey, "path1") However, this command doesn't: jsonGet(somekey, "path1 path2 path3")

    Am I missing something about how to return multiple paths (fields) from jsonGet? Should I be using the options in the function signature?

    ... or possibly change the function signature? from: JSONGet(key, path string, opts ...rjs.GetOption) (res interface{}, err error) to: JSONGet(key, path []string, opts ...rjs.GetOption) (res interface{}, err error)

  • add support for go-redis v9(redis v7.0)

    add support for go-redis v9(redis v7.0)

    I use redis v7 and go-redis v9,while go-rejson use go-redis v8,their apis have some difference,i cant pass go-redis v9's *redis.Client to SetGoRedisClient function

  • Add support for RedisJSON 2.0 full JSONPath syntax

    Add support for RedisJSON 2.0 full JSONPath syntax

    Please notice all the commands can now get full jsonpath, i.e. dynamic paths that start with a $ sign. As a result all the commands can now return multi parts of the JSON. see: https://oss.redis.com/redisjson/commands/

  • Call a command inside a transaction/pipe

    Call a command inside a transaction/pipe

    Is there a way to use a rejson command inside a transaction or pipe? Something like that:

    tx := redisClient.TXPipeline()
    tx.XAdd(&redis.XAddArgs{Stream: stream.Name, ID: "*", Values: map[string]interface{}{"msg": "New stream"}})
    tx.JSONSet(streamInfoKey(stream.Name), ".", stream)
    tx.Exec()
    
Redis client Mock Provide mock test for redis query

Redis client Mock Provide mock test for redis query, Compatible with github.com/go-redis/redis/v8 Install Confirm that you are using redis.Client the

Dec 27, 2022
GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right away.

GoBigdis GoBigdis is a persistent database that implements the Redis server protocol. Any Redis client can interface with it and start to use it right

Apr 27, 2022
Bxd redis benchmark - Redis benchmark tool for golang

使用 redis benchmark 工具, 测试 10 20 50 100 200 1k 5k 字节 value 大小,redis get set 性能。 r

Jan 22, 2022
Go-redisson: A redisson like distributed redis lock, support watchdog、reentrant lock

go-redisson a Redisson like distributed locking implementation using Redis. Installation go get github.com/cheerego/go-redisson Lock Category Mutex Ex

Dec 17, 2022
redis client implement by golang, inspired by jedis.

godis redis client implement by golang, refers to jedis. this library implements most of redis command, include normal redis command, cluster command,

Dec 6, 2022
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

Jan 1, 2023
Type-safe Redis client for Golang

Redis client for Golang ❤️ Uptrace.dev - distributed traces, logs, and errors in one place Join Discord to ask questions. Documentation Reference Exam

Jan 4, 2023
Redis client for Golang
Redis client for Golang

Redis client for Golang To ask questions, join Discord or use Discussions. Newsl

Dec 23, 2021
Redis client for Golang
Redis client for Golang

Redis client for Golang Discussions. Newsletter to get latest updates. Documentation Reference Examples RealWorld example app Other projects you may l

Dec 30, 2021
Go client for Redis

Redigo Redigo is a Go client for the Redis database. Features A Print-like API with support for all Redis commands. Pipelining, including pipelined tr

Jan 1, 2023
Go Redis Client

xredis Built on top of github.com/garyburd/redigo with the idea to simplify creating a Redis client, provide type safe calls and encapsulate the low l

Sep 26, 2022
godis - an old Redis client for Go

godis Implements a few database clients for Redis. There is a stable client and an experimental client, redis and exp, respectively. To use any of the

Apr 16, 2022
Google Go Client and Connectors for Redis

Go-Redis Go Clients and Connectors for Redis. The initial release provides the interface and implementation supporting the (~) full set of current Red

Oct 25, 2022
Redis client library for Go

go-redis go-redis is a Redis client library for the Go programming language. It's built on the skeleton of gomemcache. It is safe to use by multiple g

Nov 8, 2022
A Golang implemented Redis Server and Cluster.
A Golang implemented Redis Server and Cluster.

Godis is a golang implementation of Redis Server, which intents to provide an example of writing a high concurrent middleware using golang.

Dec 28, 2022
A golang tool to view Redis data in terminal
A golang tool to view Redis data in terminal

Redis Viewer A tool to view Redis data in terminal. Usage: KeyBoard Description ctrl+c exit redis viewer ↑ previous key ↓ next key ← previous page → n

Dec 26, 2022
High-performance framework for building redis-protocol compatible TCP servers/services

Redeo The high-performance Swiss Army Knife for building redis-protocol compatible servers/services. Parts This repository is organised into multiple

Jan 4, 2023
Simple key-value store abstraction and implementations for Go (Redis, Consul, etcd, bbolt, BadgerDB, LevelDB, Memcached, DynamoDB, S3, PostgreSQL, MongoDB, CockroachDB and many more)

gokv Simple key-value store abstraction and implementations for Go Contents Features Simple interface Implementations Value types Marshal formats Road

Dec 24, 2022
Redis Sorted Sets Benchmark

redis-zbench-go Redis Sorted Sets Benchmark Overview This repo contains code to trigger load ( ZADD ) or query (ZRANGEBYLEX key min max) benchmarks, w

May 18, 2021