Error wrongtype operation against a key holding the wrong kind of value

Redis serialization protocol (RESP) specification

Redis serialization protocol (RESP) specification

Redis clients use a protocol called RESP (REdis Serialization Protocol) to communicate with the Redis server. While the protocol was designed specifically for Redis, it can be used for other client-server software projects.

RESP is a compromise between the following things:

  • Simple to implement.
  • Fast to parse.
  • Human readable.

RESP can serialize different data types like integers, strings, and arrays. There is also a specific type for errors. Requests are sent from the client to the Redis server as arrays of strings that represent the arguments of the command to execute. Redis replies with a command-specific data type.

RESP is binary-safe and does not require processing of bulk data transferred from one process to another because it uses prefixed-length to transfer bulk data.

Note: the protocol outlined here is only used for client-server communication. Redis Cluster uses a different binary protocol in order to exchange messages between nodes.

Network layer

A client connects to a Redis server by creating a TCP connection to the port 6379.

While RESP is technically non-TCP specific, the protocol is only used with TCP connections (or equivalent stream-oriented connections like Unix sockets) in the context of Redis.

Request-Response model

Redis accepts commands composed of different arguments.
Once a command is received, it is processed and a reply is sent back to the client.

This is the simplest model possible; however, there are two exceptions:

  • Redis supports pipelining (covered later in this document). So it is possible for clients to send multiple commands at once and wait for replies later.
  • When a Redis client subscribes to a Pub/Sub channel, the protocol changes semantics and becomes a push protocol. The client no longer requires sending commands because the server will automatically send new messages to the client (for the channels the client is subscribed to) as soon as they are received.

Excluding these two exceptions, the Redis protocol is a simple request-response protocol.

RESP protocol description

The RESP protocol was introduced in Redis 1.2, but it became the
standard way for talking with the Redis server in Redis 2.0.
This is the protocol you should implement in your Redis client.

RESP is actually a serialization protocol that supports the following
data types: Simple Strings, Errors, Integers, Bulk Strings, and Arrays.

Redis uses RESP as a request-response protocol in the
following way:

  • Clients send commands to a Redis server as a RESP Array of Bulk Strings.
  • The server replies with one of the RESP types according to the command implementation.

In RESP, the first byte determines the data type:

  • For Simple Strings, the first byte of the reply is «+»
  • For Errors, the first byte of the reply is «-«
  • For Integers, the first byte of the reply is «:»
  • For Bulk Strings, the first byte of the reply is «$»
  • For Arrays, the first byte of the reply is «*«

RESP can represent a Null value using a special variation of Bulk Strings or Array as specified later.

In RESP, different parts of the protocol are always terminated with «rn» (CRLF).

RESP Simple Strings

Simple Strings are encoded as follows: a plus character, followed by a string that cannot contain a CR or LF character (no newlines are allowed), and terminated by CRLF (that is «rn»).

Simple Strings are used to transmit non binary-safe strings with minimal overhead. For example, many Redis commands reply with just «OK» on success. The RESP Simple String is encoded with the following 5 bytes:

"+OKrn"

In order to send binary-safe strings, use RESP Bulk Strings instead.

When Redis replies with a Simple String, a client library should respond with a string composed of the first character after the ‘+’
up to the end of the string, excluding the final CRLF bytes.

RESP Errors

RESP has a specific data type for errors. They are similar to
RESP Simple Strings, but the first character is a minus ‘-‘ character instead
of a plus. The real difference between Simple Strings and Errors in RESP is that clients treat errors
as exceptions, and the string that composes
the Error type is the error message itself.

The basic format is:

"-Error messagern"

Error replies are only sent when something goes wrong, for instance if
you try to perform an operation against the wrong data type, or if the command
does not exist. The client should raise an exception when it receives an Error reply.

The following are examples of error replies:

-ERR unknown command 'helloworld'
-WRONGTYPE Operation against a key holding the wrong kind of value

The first word after the «-«, up to the first space or newline, represents
the kind of error returned. This is just a convention used by Redis and is not
part of the RESP Error format.

For example, ERR is the generic error, while WRONGTYPE is a more specific
error that implies that the client tried to perform an operation against the
wrong data type. This is called an Error Prefix and is a way to allow
the client to understand the kind of error returned by the server without checking the exact error message.

A client implementation may return different types of exceptions for different
errors or provide a generic way to trap errors by directly providing
the error name to the caller as a string.

However, such a feature should not be considered vital as it is rarely useful, and a limited client implementation may simply return a generic error condition, such as false.

RESP Integers

This type is just a CRLF-terminated string that represents an integer,
prefixed by a «:» byte. For example, «:0rn» and «:1000rn» are integer replies.

Many Redis commands return RESP Integers, like INCR, LLEN, and LASTSAVE.

There is no special meaning for the returned integer. It is just an
incremental number for INCR, a UNIX time for LASTSAVE, and so forth. However,
the returned integer is guaranteed to be in the range of a signed 64-bit integer.

Integer replies are also used in order to return true or false.
For instance, commands like EXISTS or SISMEMBER will return 1 for true
and 0 for false.

Other commands like SADD, SREM, and SETNX will return 1 if the operation
was actually performed and 0 otherwise.

The following commands will reply with an integer: SETNX, DEL,
EXISTS, INCR, INCRBY, DECR, DECRBY, DBSIZE, LASTSAVE,
RENAMENX, MOVE, LLEN, SADD, SREM, SISMEMBER, SCARD.

RESP Bulk Strings

Bulk Strings are used in order to represent a single binary-safe
string up to 512 MB in length.

Bulk Strings are encoded in the following way:

  • A «$» byte followed by the number of bytes composing the string (a prefixed length), terminated by CRLF.
  • The actual string data.
  • A final CRLF.

So the string «hello» is encoded as follows:

"$5rnhellorn"

An empty string is encoded as:

"$0rnrn"

RESP Bulk Strings can also be used in order to signal non-existence of a value
using a special format to represent a Null value. In this
format, the length is -1, and there is no data. Null is represented as:

"$-1rn"

This is called a Null Bulk String.

The client library API should not return an empty string, but a nil object,
when the server replies with a Null Bulk String.
For example, a Ruby library should return ‘nil’ while a C library should
return NULL (or set a special flag in the reply object).

RESP Arrays

Clients send commands to the Redis server using RESP Arrays. Similarly,
certain Redis commands, that return collections of elements to the client,
use RESP Arrays as their replies. An example is the LRANGE command that
returns elements of a list.

RESP Arrays are sent using the following format:

  • A * character as the first byte, followed by the number of elements in the array as a decimal number, followed by CRLF.
  • An additional RESP type for every element of the Array.

So an empty Array is just the following:

"*0rn"

While an array of two RESP Bulk Strings «hello» and «world» is encoded as:

"*2rn$5rnhellorn$5rnworldrn"

As you can see after the *<count>CRLF part prefixing the array, the other
data types composing the array are just concatenated one after the other.
For example, an Array of three integers is encoded as follows:

"*3rn:1rn:2rn:3rn"

Arrays can contain mixed types, so it’s not necessary for the
elements to be of the same type. For instance, a list of four
integers and a bulk string can be encoded as follows:

*5rn
:1rn
:2rn
:3rn
:4rn
$5rn
hellorn

(The reply was split into multiple lines for clarity).

The first line the server sent is *5rn in order to specify that five
replies will follow. Then every reply constituting the items of the
Multi Bulk reply are transmitted.

Null Arrays exist as well and are an alternative way to
specify a Null value (usually the Null Bulk String is used, but for historical
reasons we have two formats).

For instance, when the BLPOP command times out, it returns a Null Array
that has a count of -1 as in the following example:

"*-1rn"

A client library API should return a null object and not an empty Array when
Redis replies with a Null Array. This is necessary to distinguish
between an empty list and a different condition (for instance the timeout
condition of the BLPOP command).

Nested arrays are possible in RESP. For example a nested array of two arrays
is encoded as follows:

*2rn
*3rn
:1rn
:2rn
:3rn
*2rn
+Hellorn
-Worldrn

(The format was split into multiple lines to make it easier to read).

The above RESP data type encodes a two-element Array consisting of an Array that contains three Integers (1, 2, 3) and an array of a Simple String and an Error.

Null elements in Arrays

Single elements of an Array may be Null. This is used in Redis replies to signal that these elements are missing and not empty strings. This
can happen with the SORT command when used with the GET pattern option
if the specified key is missing. Example of an Array reply containing a
Null element:

*3rn
$5rn
hellorn
$-1rn
$5rn
worldrn

The second element is a Null. The client library should return something
like this:

["hello",nil,"world"]

Note that this is not an exception to what was said in the previous sections, but
an example to further specify the protocol.

Send commands to a Redis server

Now that you are familiar with the RESP serialization format, you can use it to help write a Redis client library. We can further specify
how the interaction between the client and the server works:

  • A client sends the Redis server a RESP Array consisting of only Bulk Strings.
  • A Redis server replies to clients, sending any valid RESP data type as a reply.

So for example a typical interaction could be the following.

The client sends the command LLEN mylist in order to get the length of the list stored at key mylist. Then the server replies with an Integer reply as in the following example (C: is the client, S: the server).

C: *2rn
C: $4rn
C: LLENrn
C: $6rn
C: mylistrn

S: :48293rn

As usual, we separate different parts of the protocol with newlines for simplicity, but the actual interaction is the client sending *2rn$4rnLLENrn$6rnmylistrn as a whole.

Multiple commands and pipelining

A client can use the same connection in order to issue multiple commands.
Pipelining is supported so multiple commands can be sent with a single
write operation by the client, without the need to read the server reply
of the previous command before issuing the next one.
All the replies can be read at the end.

For more information, see Pipelining.

Inline commands

Sometimes you may need to send a command
to the Redis server but only have telnet available. While the Redis protocol is simple to implement, it is
not ideal to use in interactive sessions, and redis-cli may not always be
available. For this reason, Redis also accepts commands in the inline command format.

The following is an example of a server/client chat using an inline command
(the server chat starts with S:, the client chat with C:)

C: PING
S: +PONG

The following is an example of an inline command that returns an integer:

C: EXISTS somekey
S: :0

Basically, you write space-separated arguments in a telnet session.
Since no command starts with * that is instead used in the unified request
protocol, Redis is able to detect this condition and parse your command.

High performance parser for the Redis protocol

While the Redis protocol is human readable and easy to implement, it can
be implemented with a performance similar to that of a binary protocol.

RESP uses prefixed lengths to transfer bulk data, so there is
never a need to scan the payload for special characters, like with JSON, nor to quote the payload that needs to be sent to the
server.

The Bulk and Multi Bulk lengths can be processed with code that performs
a single operation per character while at the same time scanning for the
CR character, like the following C code:

#include <stdio.h>

int main(void) {
    unsigned char *p = "$123rn";
    int len = 0;

    p++;
    while(*p != 'r') {
        len = (len*10)+(*p - '0');
        p++;
    }

    /* Now p points at 'r', and the len is in bulk_len. */
    printf("%dn", len);
    return 0;
}

After the first CR is identified, it can be skipped along with the following
LF without any processing. Then the bulk data can be read using a single
read operation that does not inspect the payload in any way. Finally,
the remaining CR and LF characters are discarded without any processing.

While comparable in performance to a binary protocol, the Redis protocol is
significantly simpler to implement in most high-level languages,
reducing the number of bugs in client software.

If you’re getting error number 1064 that reads something like “1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘INTEGER )’ at line 1“, it could be that you’re using the wrong term for the integer.

MySQL doesn’t let us use just the INTEGER keyword when converting to an integer. We need to use either SIGNED or UNSIGNED, optionally followed by INTEGER or INT. When we do this, it produces a signed or unsigned BIGINT value.

Continue reading

If you’re getting an error that reads something like “Msg 3728, Level 16, State 1, Line 1
‘DF__Dogs__DogId__6FE99F9F’ is not a constraint
“, it’s probably because you’re trying to drop a constraint that isn’t in the database.

To fix this issue, check to make sure the constraint exists before dropping it. Alternatively, use the IF EXISTS clause to drop the constraint only if it exists.

Continue reading

If you’re getting an error that reads “ERR wrong number of arguments for ‘hrandfield’ command“, it’s probably because you’re not passing any arguments when using the HRANDFIELD command.

The HRANDFIELD command requires at least one argument, and accepts up to three arguments (at the time of writing).

Continue reading

If you get an error that reads “WRONGTYPE Operation against a key holding the wrong kind of value” when setting a hash with a command like HSET or HSETNX, it’s probably because you’re trying to set a non-hash key that already exists. In other words, the key already exists, but it doesn’t contain a hash.

To fix this issue, be sure to use these commands on keys that either don’t already exist, or contain a hash.

Continue reading

If you’re getting error 1045 that reads something like “Access denied for user ‘root’@’localhost’“, it’s because you’re trying to log in to MySQL without the right credentials.

This usually happens when we provide the wrong password. But there could also be another cause. For example, we could be trying to do something as the root user that requires a password, but the root user hasn’t yet had its password set.

To fix this issue, be sure to provide the correct password when connecting to MySQL.

Continue reading

If you’re getting an error that reads “ERR wrong number of arguments for ‘srandmember’ command” in Redis, it’s probably because you’re calling the SRANDMEMBER command without any arguments.

To fix this issue, make sure you pass the correct number of arguments. At the time of writing, the SRANDMEMBER command requires at least one argument, and accepts an optional second argument.

Continue reading

If you get an error that reads “WRONGTYPE Operation against a key holding the wrong kind of value” when using the ZINTER command in Redis, it’s probably because you’re passing a key with the wrong data type.

To fix this issue, be sure that each key you pass to the ZINTER command is either a set or a sorted set.

Continue reading

If you’re getting an error that reads “ERR wrong number of arguments for ‘smismember’ command” in Redis, it’s because you’re calling the SMISMEMBER command with the wrong number of arguments.

To fix this issue, make sure you’re passing the correct number of arguments. This command accepts two or more arguments, which represents a key and one or more members to check against that key.

Continue reading

If you’re getting an error that reads “NEXT VALUE FOR function does not support the PARTITION BY clause” in SQL Server, it’s probably because you’re trying to use the PARTITION BY sub clause in an OVER clause when using NEXT VALUE FOR to increment a sequence object.

In other words, the NEXT VALUE FOR function does not support the PARTITION BY sub clause of the OVER clause.

To fix this issue, either remove the PARTITION BY clause or change the statement to use another method for partitioning the results.

Continue reading

If you get an error that reads “WRONGTYPE Operation against a key holding the wrong kind of value” when using the ZUNION or ZUNIONSTORE commands in Redis, it’s because you’re passing a key with the wrong data type.

To fix this issue, make sure the keys you pass to these commands contain either sets or sorted sets. Although these commands are for sorted sets, they also work with non-sorted sets.

Continue reading

RedisRedis is an in-memory key-value pair database.

Redis is extremely fast, as the operation happens in the memory. Redis also provides on-disk persistence and built-in replication.

In Redis, you can use these data structures: 1) String 2) Hash 3) List 4) Set 5) Sorted Set.

There is no integer or float data type in Redis. But, you can use string as integer, and there are few String commands that will allow you to manipulate string values are numbers.

In this tutorial, we’ll explain all the following Redis string (and number) commands with examples.

In our examples, we’ll explain both redis-cli and Redis Python Library version of these string commands.

  • SET and GET
  • SETEX and PSETEX
  • SETNX and SETXX
  • DEL
  • APPEND
  • STRLEN
  • SETRANGE and GETRANGE
  • INCR, INCRBY and INCRBYFLOAT
  • DECR and DECRBY
  • MSET and MGET
  • MSETNX

Redis CLI and Python examples

This article explains all the Redis string commands using the following two methods: 1) Redis CLI 2) Redis Python Library

Redis CLI

You can start the Redis command line interface using “redis-cli” command. On your server, when you type redis-cli, you’ll get a Redis command line prompt as shown below. In this prompt you can type any Redis commands.

# redis-cli
127.0.0.1:6379>

In the above:

  • redis-cli is the command that you type on Linux prompt to start the Redis command line interface
  • 127.0.0.1:6379> – This is the redis prompt where you can type all Redis commands. 6379 is the default port on the local server (127.0.0.1) where the Redis server is running.

Redis Python Library

You can also use Redis from several programming language. In our tutorial, we’ll show how to use Redis string commands in Python.

For this, you should import the Redis library inside your Python program, and then create a connection to the server, and then using that redis connection, call the Redis commands.

# python
>>> import redis;
>>> con = redis.Redis("localhost");

In the above:

  • python is the command that you type on Linux prompt to start the python command line interface.
  • >>> is the python prompt where you type python commands.
  • import redis; – This is the python command to import redis library before we can start using redis command.
  • con = redis.Redis(“localhost”); – Using the redis python library, we are creating a new connection to Redis server. We’ll be using this “con” connection inside python to call Redis commands.

If you are using PHP: How to Use Redis with PHP using PhpRedis with Examples

1. SET: Assign Value to a Key

Using SET command, you can assign a value to a key as shown below.

127.0.0.1:6379> SET site "thegeekstuff"
OK

In the above:

  • SET is the redis command from redis-cli
  • site is the name of the key
  • “thegeekstuff” is the value that we are assigning to site.

In Python:

>>> con.set("site","thegeekstuff");
True

Note: In the python redis library, for all the redis commands, you need to specify the name of the key within double quotes. If not, you’ll get the “NameError: name is not defined” error.

>>> con.set(site,"thegeekstuff");
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'site' is not defined

2. GET: Retrieve Value from a Key

Using GET command, you can retrive the value from a key as shown below.

127.0.0.1:6379> GET site
"thegeekstuff"

If a key doesn’t exist, you’ll see “nil” as the output.

127.0.0.1:6379> GET forum
(nil)

In Python:

>>> con.get("site");
'thegeekstuff'

Note: For ALL redis string commands, when you are trying to manipulate a key that is of a different datatype (anything other than string), then you’ll get the following WRONGTYPE error message. This just means that the key that you are using is not of string datatype.

127.0.0.1:6379> GET multiplesites
(error) WRONGTYPE Operation against a key holding the wrong kind of value

3. SET..EX, SETEX, EXPIRE: Expire the Key in X Seconds

You can also expire the value of the key after a certain time. For this, use the EX option (EX stands for Expire) in the SET command as shown below.

In the following example, the value of the key site is set and it will expire after 10 seconds.

127.0.0.1:6379> SET site "thegeekstuff" EX 10
OK

Note: The above SET .. EX option is available only From Redis 2.6.12 version.

You can also use SETEX command to set the EX value in seconds as shown below. But, Redis recommends that you start using the above SET..EX option, as SETEX might be deprecated in the future.

127.0.0.1:6379> SETEX site 10 "thegeekstuff"
OK

Another option to expire a key is to use EXPIRE command as shown below. The following will expire the site key in 10 seconds.

127.0.0.1:6379> SET site "thegeekstuff"
OK

127.0.0.1:6379> EXPIRE site 10
(integer) 0

In Python use set command with ex parameter as shown below.

>>> con.set("site","thegeekstuff",ex=10);
True

In Python you can also use setex command:

>>> con.setex("site","thegeekstuff",10);
True

4. SET..PX, PSETEX: Expire the Key in X milliseconds

Instead of expiring a key in seconds, you can also expire a key in milliseconds using PX option while setting the value using SET command as shown below.

In the following example, the value of the key site is set and it will expire after 100 milliseconds.

127.0.0.1:6379> SET site "thegeekstuff" PX 100
OK

You can also use PSETEX command to set the PX value in milliseconds as shown below. But, Redis recommends that you start using the above SET..PX option, as PSETEX might be deprecated in the future.

127.0.0.1:6379> PSETEX site 100 "thegeekstuff" 
OK

Note: There is no SETPX command in Redis. Instead, use the above PSETEX command.

In Python use set command with px parameter as shown below.

>>> con.set("site","thegeekstuff",px=100);
True

5. SET..NX, SETNX: Set Value ONLY When Key doesn’t Exist

SET command by default will overwrite the previous value, if you try to set the same key again. As you see below, we’ve overwritten the value of site key with new value.

127.0.0.1:6379> SET site "thegeekstuff (NEW)"
OK

127.0.0.1:6379> GET site
"thegeekstuff (NEW)"

But, if a key exists, and you don’t want to overwrite the value, then use the NX option with SET command as shown below.

First, let us set the value back to original.

SET site "thegeekstuff"

Next, Use the NX option along with SET command as shown below.

127.0.0.1:6379> SET site "thegeekstuff (NEW)" NX
(nil)

As you see from the above output, it didn’t say OK, it said “(nil)”, which means that the SET command didn’t change any value.

As you see below, the value of site key didn’t change.

127.0.0.1:6379> GET site
"thegeekstuff"

You can also use SETNX command which does exactly the same as the above SET..NX. In the following example, since the site key already exists, it didn’t set the new value.

127.0.0.1:6379> SETNX site "thegeekstuff (NEW)"
(integer) 0

In Python:

>>> con.set("site","thegeekstuff (NEW)",nx=True);

>>> con.setnx("site","thegeekstuff (NEW)");
False

>>> con.get("site");
'thegeekstuff'

6. SET..XX: Set Value ONLY When Key Exist

In the following example, we’ll set the value for the key “blog” only if that key exists previously.

Since this is the first time we are setting the value for the key blog, it failed as shown below.

127.0.0.1:6379> SET blog "thegeekstuff" XX
(nil)

127.0.0.1:6379> GET blog
(nil)

In the following example, we’ll set a new value for the key “site” only if that key exists previously.

Since we already had the key site, the new value was set properly as shown below.

127.0.0.1:6379> SET site "thegeekstuff (NEW)" XX
OK

127.0.0.1:6379> GET site
"thegeekstuff (NEW)"

In Python:

>>> con.set("blog","thegeekstuff",xx=True);

7. DEL: Delete a Key

DEL will delete the given key. The output will indicate how many keys it has deleted. In this example, the output is an interger value of 1, which indicates that it has deleted 1 key.

127.0.0.1:6379> GET site
"thegeekstuff"

127.0.0.1:6379> DEL site
(integer) 1

If the given key doesn’t exist, it wil simply ignore it. As you see below, the output is an interger value of 0, which indicates that it didn’t delete any key.

127.0.0.1:6379> DEL site
(integer) 0

You can also delete multiple keys in a single DEL command as shown below.

The output of the following command is an integer value of 2, which indicates that it has deleted 2 keys. This is because we never had a key called “forum”.

127.0.0.1:6379> DEL site blog forum
(integer) 2

In Python, when delete is successful:

>>> con.delete("site");
1

In Python, when key doesn’t exist, delete returns 0:

>>> con.delete("site");
0

In Python, you can also use delete command to delete multiple keys:

>>> con.delete("site","blog","forum");
2

8. APPEND: Append Given Value to an Existing Value of a Key

APPEND command will append the given value to the end of the existing value for a key.

First, set an initial value to the site key.

127.0.0.1:6379> SET site "the"
OK

Next, use the APPEND command to append value to an existing key. The output of the APPEND command will display the total number of characters in the string after the APPEND is completed.

127.0.0.1:6379> APPEND site "geek"
(integer) 7

127.0.0.1:6379> APPEND site "stuff"
(integer) 12

127.0.0.1:6379> GET site
"thegeekstuff"

If a key doesn’t exist previously, APPEND command behave like a SET command and will assign the value to the key as shown below. In this example, we never had a key called forum.

127.0.0.1:6379> APPEND forum "TGS"
(integer) 3

127.0.0.1:6379> GET forum
"TGS"

In Python:

>>> con.set("site","the");
True

>>> con.append("site","geek");
7L

>>> con.append("site","stuff");
12L

>>> con.get("site");
'thegeekstuff'

9. STRLEN: Get the Lenght of the Value of a Key

STRLEN command will get the number of characters in the value. Basically this will return the lenght of the string value stored in the given key as shown below.

127.0.0.1:6379> GET site
"thegeekstuff"

127.0.0.1:6379> STRLEN site
(integer) 12

127.0.0.1:6379> GET forum
"TGS"

127.0.0.1:6379> STRLEN forum
(integer) 3

When a key doesn’t exist, it will return 0 as shown below. In this example, we don’t have a key called database.

127.0.0.1:6379> STRLEN database
(integer) 0

In Python:

>>> con.strlen("site");
12

10. SETRANGE: Replace Part of the Value (Substring Replace Operation)

For this example, we’ll use the following distro string that has the value as “Linux OS”

127.0.0.1:6379> SET distro "Linux OS"
OK

127.0.0.1:6379> GET distro
"Linux OS"

Using SETRANGE command, we can replace part of the string starting from a speficied offset value until the end of the string.

In the following example, the values starting from offset 6 until the end of the string (which in the above example is “OS”) will be replaced by the given string (“Operating System”)

The output of the SETRANGE command will the total number of characters in the key after the SETRANGE is completed.

127.0.0.1:6379> SETRANGE distro 6 "Operating System"
(integer) 22

127.0.0.1:6379> GET distro
"Linux Operating System"

Note: When you calculating the string position, the offset starting value is 0. i.e Start counting from 0.

In Python:

>>> con.set("distro","Linux OS");
True

>>> con.setrange("distro",6,"Operating System");
22

>>> con.get("distro");
'Linux Operating System'

11. GETRANGE: Retrieve Part of the Value (Get Substring Operation)

The following example will get the substring starting from offset 3 until offset 6.

127.0.0.1:6379> GET site
"thegeekstuff"

127.0.0.1:6379> GETRANGE site 3 6
"geek"

Two things to keep in mind:

  • The offset value for the 1st character in the string is 0 (and not 1).
  • The last value in the GETRANGE is not the total number of characters to extract. It is the offset value (the location) of the last character (until which) that you want extract.

You can also give negative value for the offset, which will be calculated from the last position. For example, offset of -1 indicates the last character, -2 indicates the 2nd character from last, etc.

The following example will extract the last 5 characters. i.e Starting from offset -5 until offset -1.

127.0.0.1:6379> GETRANGE site -5 -1
"stuff"

Again, please note that the 1st character position is offset 0, and the last character position represented by negative offset value is -1. So, the following example will start from 1st position until the last position, giving us the whole string back.

127.0.0.1:6379> GETRANGE site 0 -1
"thegeekstuff"

If the last offset (end offset) is way out of range (i.e greater than the total number of characters in the string), it will get until the end of the string. In the following example, offset value of 25 is greater than the total number of characters in the string. So, it started from offset 7 and extracted the values until the end of the string.

127.0.0.1:6379> GETRANGE site 7 25
"stuff"

In Python:

>>> con.getrange("site",3,6);
'geek'

>>> con.getrange("site",-5,-1);
'stuff'

>>> con.getrange("site",0,-1);
'thegeekstuff'

>>> con.getrange("site",7,25);
'stuff'

12. GETSET: Set New Value and Return Old Value

As the name implies, GETSET is a combination of GET and SET command. So, it GETs the old value first and displays it. After that, it sets the given value to the key.

127.0.0.1:6379> GETSET site "The Geek Stuff Website"
"thegeekstuff"

127.0.0.1:6379> GET site
"The Geek Stuff Website"

In Python:

>>> con.getset("site","The Geek Stuff Website");
'thegeekstuff'

>>> con.get("site");
'The Geek Stuff Website'

13. INCR: Increment the Value by One

As we explained earlier, there is no number concept in Redis datatypes. Redis doesn’t have interger or float datatype. Redis will use string values as integers using string related commands that are specifically designed to manipulate numbers inside a string value.

This increments the value of the given key by one. The output of the INCR command will be the final value of the key after the increment.

127.0.0.1:6379> SET count 5
OK

127.0.0.1:6379> INCR count
(integer) 6

127.0.0.1:6379> GET count
"6"

Note:When you try to increment an existing key that has a string value, you’ll get the following error message.

127.0.0.1:6379> GET site
"thegeekstuff"

127.0.0.1:6379> INCR site
(error) ERR value is not an integer or out of range

Also, when you try to increment a key that doesn’t exist, it will create that key, set the value to 0, and then increment it by one as shown below.

127.0.0.1:6379> GET stat
(nil)

127.0.0.1:6379> INCR stat
(integer) 1

127.0.0.1:6379> GET stat
"1"

In Python:

>>> con.set("count",1);
True

>>> con.incr("count");
2

>>> con.get("count");
'2'

In python redis library, you’ll get the following exception when you try to increment a key that has string value.

>>> con.incr("site");
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build/bdist.linux-x86_64/egg/redis/client.py", line 915, in incr
  File "build/bdist.linux-x86_64/egg/redis/client.py", line 573, in execute_command
  File "build/bdist.linux-x86_64/egg/redis/client.py", line 585, in parse_response
  File "build/bdist.linux-x86_64/egg/redis/connection.py", line 582, in read_response
redis.exceptions.ResponseError: value is not an integer or out of range
>>> con.get("site");
'thegeekstuff'

14. INCRBY: Increase the Value by Given Increment

Instead of incrementing the number by 1, you can increatement it by any given number using INCRBY command as shown below.

In the following example, we are incrementing the key “count” by 3.

127.0.0.1:6379> SET count 5
OK

127.0.0.1:6379> INCRBY count 3
(integer) 8

127.0.0.1:6379> GET count
"8"

Note: Just like INCR, when you try INCRBY on a key that doesn’t exist, it will create that key, set the value to 0, and then do the increment as shown below.

127.0.0.1:6379> GET statistics
(nil)

127.0.0.1:6379> INCRBY statistics 5
(integer) 5

127.0.0.1:6379> GET statistics
"5"

In Python:

>>> con.set("count",1);
True

>>> con.incrby("count",3);
4

>>> con.get("count");
'4'

Note: In python redis library, we can also use incr command itself to increment it by any value as shown below.

>>> con.set("count",1);
True

>>> con.incr("count",3);
4

15. DECR: Decrease the Value by One

This is similar to INCR, but DECR will decrease the value by one as shown below.

127.0.0.1:6379> SET count 5
OK

127.0.0.1:6379> DECR count
(integer) 4

In Python:

>>> con.set("count",10);
True

>>> con.decr("count")
9

16. DECRBY: Decrease the Value by Given Decrement

This is similar to INCRBY, but DECRBY will decrease the value by the given number as shown below.

127.0.0.1:6379> SET count 5
OK

127.0.0.1:6379> DECRBY count 2
(integer) 3

In Python, we have incrby function, but there is no decrby function. However, we can use the decr function itself, but pass the value to be decremented as parameter:

>>> con.get("count");
'10'

>>> con.decr("count",3);
7

17. INCRBYFLOAT: Increase the Float Value by Given Increment (Fraction Values)

You can increment a number with a float value (number with decimal point values) using the INCRBYFLOAT function as shown below.

127.0.0.1:6379> SET price 93.5
OK

127.0.0.1:6379> GET price
"93.5"

127.0.0.1:6379> INCRBYFLOAT price 0.3
"93.8"

This works even when the key contains an integer value and not float value as shown below.

127.0.0.1:6379> SET count 3
OK

127.0.0.1:6379> INCRBYFLOAT count 0.3
"3.3"

If you don’t specify a value to increment by, you’ll get the following error message:

127.0.0.1:6379> INCRBYFLOAT price
(error) ERR wrong number of arguments for 'incrbyfloat' command

When you try to use INCRBYFLOAT on a string value, you’ll get the following error message.

127.0.0.1:6379> INCRBYFLOAT site 0.3
(error) ERR value is not a valid float

127.0.0.1:6379> GET site
"thegeekstuff"

In Python:

>>> con.set("price",93.5);
True

>>> con.incrbyfloat("price",0.3);
93.799999999999997

In python, the last parameter is opitional, if you don’t specify a value, it will be incremented by 1.0 as shown below.

>>> con.set("count",3);
True

>>> con.incrbyfloat("count");
4.0

18. MSET: Set Multiple Keys and Values

MSET is similar to SET command, but this can set multiple key/value pair using one command as shown below.

127.0.0.1:6379> MSET site "thegeekstuff" blog "TGS" forum "The Geek Stuff"
OK

127.0.0.1:6379> GET site
"thegeekstuff"

127.0.0.1:6379> GET blog
"TGS"

127.0.0.1:6379> GET forum
"The Geek Stuff"

In Python, you first have to define a dict mapping as shown below. “sites” is a dict mapping which has three key-values.

>>> sites = {"site":"thegeekstuff", "blog":"TGS", "forum":"The Geek Stuff"}

Next, set the above “sites” dict using mset as shown below.

>>> con.mset(sites);
True

Verify:

>>> con.get("site")
'thegeekstuff'

>>> con.get("blog")
'TGS'

>>> con.get("forum")
'The Geek Stuff'

19. MGET: Retrieve Values from Multiple Keys

MGET is similar to GET command, but this can retrive and display values of multiple keys using one command as shown below.

127.0.0.1:6379> MGET site blog forum
1) "thegeekstuff"
2) "TGS"
3) "The Geek Stuff"

In Python:

>>> con.mget("site","blog","forum");
['thegeekstuff', 'TGS', 'The Geek Stuff']

20. MSETNX: Set Value ONLY When ALL Keys Don’t Exist

This is a combination of SETNX and MSET command. This will set the values for the given keys only when ALL of them don’t already exist. This will not perform any of the assignment even if one of the key already exists.

For example, the following will set the values for the three keys (site, author and email) only when ALL three of them don’t exists earlier.

In our case, the key “site” already exists. So, this will not set the value for all three of these keys.

127.0.0.1:6379> MSETNX site "The Geek Stuff" author "Ramesh Natarajan" email "ramesh@thegeekstuff.com" 
(integer) 0

As you see below, the site key still has old value, and author and email are not defined.

127.0.0.1:6379> MGET site author email
1) "thegeekstuff"
2) (nil)
3) (nil)

But, if we delete the “site” key and try again, MSETMX will work and set the values for all the three keys as shown below.

127.0.0.1:6379> DEL site
(integer) 1

127.0.0.1:6379> MSETNX site "The Geek Stuff" author "Ramesh Natarajan" email "ramesh@thegeekstuff.com" 
(integer) 1

127.0.0.1:6379> MGET site author email
1) "The Geek Stuff"
2) "Ramesh Natarajan"
3) "ramesh@thegeekstuff.com"

In Python, define a dict mapping that contains multiple key/value pair, and use that as a parameter to msetnx as shown below:

>>> myargs = {"site":"The Geek Stuff", "author":"Ramesh Natarajan", "email":"ramesh@thegeekstuff.com"}

>>> con.msetnx(myargs);
False

>>> con.mget("site","author","email");
['thegeekstuff', None, None]

Понравилась статья? Поделить с друзьями:
  • Error wrong size dds my summer car
  • Error wrong parameter found at position
  • Error wrong code работа системы обновлений заблокирована битрикс
  • Error wrong code bitrix
  • Error wrong checksum repetier