0
# RedisJSON
1
2
RedisJSON provides native JSON data type support for Redis, allowing storage, indexing, and manipulation of JSON documents. It offers path-based operations for efficient JSON document updates without retrieving the entire document.
3
4
```python
5
import redis
6
from typing import Any, Dict, List, Optional, Union
7
8
# Access JSON functionality through the json() method
9
r = redis.Redis()
10
json_client = r.json()
11
```
12
13
## Capabilities
14
15
### JSON Document Operations
16
17
Core JSON document storage and retrieval operations accessed via `redis_client.json()`.
18
19
```python { .api }
20
# JSON client obtained via r.json()
21
class JSON:
22
def set(
23
self,
24
name: str,
25
path: str,
26
obj: Any,
27
nx: Optional[bool] = False,
28
xx: Optional[bool] = False,
29
decode_keys: Optional[bool] = False
30
) -> Optional[str]: ...
31
32
def get(
33
self,
34
name: str,
35
*args: str,
36
no_escape: Optional[bool] = False
37
) -> Optional[List[Any]]: ...
38
39
def delete(self, name: str, path: str = "$") -> Optional[int]: ...
40
41
def forget(self, name: str, path: str = "$") -> Optional[int]: ...
42
43
def clear(self, name: str, path: str = "$") -> int: ...
44
45
def type(self, name: str, path: Optional[str] = "$") -> List[str]: ...
46
47
def strlen(self, name: str, path: str = "$") -> List[Optional[int]]: ...
48
49
def toggle(self, name: str, path: str = "$") -> List[int]: ...
50
```
51
52
### JSON Array Operations
53
54
Array manipulation operations for JSON arrays within documents.
55
56
```python { .api }
57
def arrappend(
58
self,
59
name: str,
60
path: Optional[str] = "$",
61
*args: Any
62
) -> List[Optional[int]]: ...
63
64
def arrindex(
65
self,
66
name: str,
67
path: str,
68
scalar: int,
69
start: Optional[int] = None,
70
stop: Optional[int] = None
71
) -> List[Optional[int]]: ...
72
73
def arrinsert(
74
self,
75
name: str,
76
path: str,
77
index: int,
78
*args: Any
79
) -> List[Optional[int]]: ...
80
81
def arrlen(self, name: str, path: Optional[str] = "$") -> List[Optional[int]]: ...
82
83
def arrpop(
84
self,
85
name: str,
86
path: Optional[str] = "$",
87
index: Optional[int] = -1
88
) -> List[Optional[str]]: ...
89
90
def arrtrim(
91
self,
92
name: str,
93
path: str,
94
start: int,
95
stop: int
96
) -> List[Optional[int]]: ...
97
```
98
99
### JSON Object Operations
100
101
Object manipulation operations for JSON objects within documents.
102
103
```python { .api }
104
def objkeys(self, name: str, path: Optional[str] = "$") -> List[Optional[List[str]]]: ...
105
106
def objlen(self, name: str, path: Optional[str] = "$") -> List[Optional[int]]: ...
107
```
108
109
### JSON Number Operations
110
111
Numeric operations for JSON number values.
112
113
```python { .api }
114
def numincrby(
115
self,
116
name: str,
117
path: str,
118
number: int
119
) -> str: ...
120
121
def nummultby(
122
self,
123
name: str,
124
path: str,
125
number: int
126
) -> str: ...
127
```
128
129
### JSON String Operations
130
131
String manipulation operations for JSON string values.
132
133
```python { .api }
134
def strappend(
135
self,
136
name: str,
137
path: str,
138
json_str: str
139
) -> List[Optional[int]]: ...
140
141
def strlen(self, name: str, path: str = "$") -> List[Optional[int]]: ...
142
```
143
144
### JSON Utility Operations
145
146
Utility operations for JSON document analysis and debugging.
147
148
```python { .api }
149
def debug_memory(self, name: str, path: str = "$") -> List[int]: ...
150
151
def resp(self, name: str, path: Optional[str] = "$") -> List[Any]: ...
152
```
153
154
## Usage Examples
155
156
### Basic JSON Document Operations
157
158
```python
159
import redis
160
import json
161
162
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
163
164
# Store JSON document
165
user_data = {
166
"id": 1001,
167
"name": "John Doe",
168
"email": "john@example.com",
169
"profile": {
170
"age": 30,
171
"city": "New York",
172
"skills": ["Python", "Redis", "JSON"]
173
},
174
"active": True
175
}
176
177
# Set JSON document
178
r.json().set("user:1001", "$", user_data)
179
180
# Get entire document
181
user = r.json().get("user:1001")
182
print(f"User: {user}")
183
184
# Get specific fields
185
name = r.json().get("user:1001", "$.name")
186
email = r.json().get("user:1001", "$.email")
187
print(f"Name: {name}, Email: {email}")
188
189
# Get nested field
190
city = r.json().get("user:1001", "$.profile.city")
191
print(f"City: {city}")
192
```
193
194
### JSON Path Operations
195
196
```python
197
import redis
198
199
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
200
201
# Complex JSON document
202
product_data = {
203
"id": "P001",
204
"name": "Gaming Laptop",
205
"price": 1299.99,
206
"specs": {
207
"cpu": "Intel i7",
208
"ram": "16GB",
209
"storage": "512GB SSD"
210
},
211
"tags": ["gaming", "portable", "performance"],
212
"reviews": [
213
{"rating": 5, "comment": "Excellent!"},
214
{"rating": 4, "comment": "Good performance"}
215
],
216
"in_stock": True
217
}
218
219
r.json().set("product:P001", "$", product_data)
220
221
# Get multiple paths
222
result = r.json().get("product:P001", "$.name", "$.price", "$.in_stock")
223
print(f"Product info: {result}")
224
225
# Update specific field
226
r.json().set("product:P001", "$.price", 1199.99)
227
228
# Update nested field
229
r.json().set("product:P001", "$.specs.ram", "32GB")
230
231
# Check updated values
232
price = r.json().get("product:P001", "$.price")
233
ram = r.json().get("product:P001", "$.specs.ram")
234
print(f"Updated price: {price}, RAM: {ram}")
235
```
236
237
### JSON Array Manipulation
238
239
```python
240
import redis
241
242
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
243
244
# Create document with arrays
245
playlist_data = {
246
"name": "My Favorites",
247
"songs": ["Song A", "Song B", "Song C"],
248
"ratings": [4.5, 3.8, 4.9],
249
"metadata": {
250
"created": "2024-01-01",
251
"genres": ["rock", "pop"]
252
}
253
}
254
255
r.json().set("playlist:1", "$", playlist_data)
256
257
# Append to array
258
r.json().arrappend("playlist:1", "$.songs", "Song D", "Song E")
259
260
# Insert into array at specific position
261
r.json().arrinsert("playlist:1", "$.songs", 1, "New Song")
262
263
# Get array length
264
length = r.json().arrlen("playlist:1", "$.songs")
265
print(f"Songs count: {length}")
266
267
# Find element in array
268
index = r.json().arrindex("playlist:1", "$.songs", "Song B")
269
print(f"Song B is at index: {index}")
270
271
# Pop element from array
272
popped = r.json().arrpop("playlist:1", "$.songs", -1) # Pop last element
273
print(f"Popped song: {popped}")
274
275
# Trim array
276
r.json().arrtrim("playlist:1", "$.songs", 0, 2) # Keep first 3 elements
277
278
# Check final array
279
songs = r.json().get("playlist:1", "$.songs")
280
print(f"Final songs: {songs}")
281
```
282
283
### JSON Object Operations
284
285
```python
286
import redis
287
288
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
289
290
# Create document with nested objects
291
config_data = {
292
"database": {
293
"host": "localhost",
294
"port": 5432,
295
"name": "myapp"
296
},
297
"cache": {
298
"redis_host": "localhost",
299
"redis_port": 6379,
300
"ttl": 3600
301
},
302
"features": {
303
"authentication": True,
304
"logging": True,
305
"monitoring": False
306
}
307
}
308
309
r.json().set("config:app", "$", config_data)
310
311
# Get object keys
312
db_keys = r.json().objkeys("config:app", "$.database")
313
feature_keys = r.json().objkeys("config:app", "$.features")
314
print(f"Database keys: {db_keys}")
315
print(f"Feature keys: {feature_keys}")
316
317
# Get object lengths
318
db_len = r.json().objlen("config:app", "$.database")
319
features_len = r.json().objlen("config:app", "$.features")
320
print(f"Database fields: {db_len}, Feature flags: {features_len}")
321
322
# Add new fields to objects
323
r.json().set("config:app", "$.database.ssl", True)
324
r.json().set("config:app", "$.features.analytics", True)
325
326
# Check updated objects
327
database = r.json().get("config:app", "$.database")
328
features = r.json().get("config:app", "$.features")
329
print(f"Updated database: {database}")
330
print(f"Updated features: {features}")
331
```
332
333
### JSON Numeric Operations
334
335
```python
336
import redis
337
338
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
339
340
# Create document with numeric values
341
stats_data = {
342
"user_id": 1001,
343
"stats": {
344
"score": 100,
345
"level": 5,
346
"experience": 2500.75,
347
"multiplier": 1.5
348
},
349
"counters": {
350
"games_played": 15,
351
"wins": 12,
352
"losses": 3
353
}
354
}
355
356
r.json().set("user_stats:1001", "$", stats_data)
357
358
# Increment numeric values
359
r.json().numincrby("user_stats:1001", "$.stats.score", 25)
360
r.json().numincrby("user_stats:1001", "$.stats.experience", 100.25)
361
r.json().numincrby("user_stats:1001", "$.counters.games_played", 1)
362
r.json().numincrby("user_stats:1001", "$.counters.wins", 1)
363
364
# Multiply numeric values
365
r.json().nummultby("user_stats:1001", "$.stats.multiplier", 1.1)
366
367
# Check updated values
368
score = r.json().get("user_stats:1001", "$.stats.score")
369
experience = r.json().get("user_stats:1001", "$.stats.experience")
370
multiplier = r.json().get("user_stats:1001", "$.stats.multiplier")
371
games_played = r.json().get("user_stats:1001", "$.counters.games_played")
372
373
print(f"Score: {score}")
374
print(f"Experience: {experience}")
375
print(f"Multiplier: {multiplier}")
376
print(f"Games played: {games_played}")
377
```
378
379
### JSON String Operations
380
381
```python
382
import redis
383
384
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
385
386
# Create document with string values
387
message_data = {
388
"id": "msg_001",
389
"content": "Hello",
390
"metadata": {
391
"author": "John",
392
"tags": "#important"
393
}
394
}
395
396
r.json().set("message:001", "$", message_data)
397
398
# Append to string values
399
r.json().strappend("message:001", "$.content", " World!")
400
r.json().strappend("message:001", "$.metadata.tags", " #urgent")
401
402
# Get string lengths
403
content_len = r.json().strlen("message:001", "$.content")
404
tags_len = r.json().strlen("message:001", "$.metadata.tags")
405
print(f"Content length: {content_len}")
406
print(f"Tags length: {tags_len}")
407
408
# Check updated strings
409
content = r.json().get("message:001", "$.content")
410
tags = r.json().get("message:001", "$.metadata.tags")
411
print(f"Content: {content}")
412
print(f"Tags: {tags}")
413
```
414
415
### JSON Document Management
416
417
```python
418
import redis
419
420
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
421
422
# Create complex document
423
document = {
424
"document_id": "doc_001",
425
"title": "Project Plan",
426
"sections": [
427
{"name": "Introduction", "pages": 2},
428
{"name": "Requirements", "pages": 5},
429
{"name": "Implementation", "pages": 10}
430
],
431
"metadata": {
432
"created_by": "Alice",
433
"version": 1.0,
434
"tags": ["project", "planning"],
435
"archived": False
436
}
437
}
438
439
r.json().set("document:001", "$", document)
440
441
# Check data types
442
title_type = r.json().type("document:001", "$.title")
443
sections_type = r.json().type("document:001", "$.sections")
444
archived_type = r.json().type("document:001", "$.metadata.archived")
445
446
print(f"Title type: {title_type}")
447
print(f"Sections type: {sections_type}")
448
print(f"Archived type: {archived_type}")
449
450
# Toggle boolean value
451
r.json().toggle("document:001", "$.metadata.archived")
452
453
# Clear array (remove all elements but keep array)
454
r.json().clear("document:001", "$.metadata.tags")
455
456
# Delete specific path
457
r.json().delete("document:001", "$.metadata.version")
458
459
# Check document structure after modifications
460
result = r.json().get("document:001")
461
print(f"Modified document: {result}")
462
463
# Get memory usage (debugging)
464
memory_usage = r.json().debug_memory("document:001", "$")
465
print(f"Memory usage: {memory_usage} bytes")
466
```
467
468
### Conditional JSON Operations
469
470
```python
471
import redis
472
473
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
474
475
# Create or update with conditions
476
profile_data = {
477
"username": "johndoe",
478
"email": "john@example.com",
479
"settings": {
480
"theme": "dark",
481
"notifications": True
482
}
483
}
484
485
# Set only if key doesn't exist (NX - Not eXists)
486
created = r.json().set("profile:new_user", "$", profile_data, nx=True)
487
print(f"New profile created: {created}")
488
489
# Try to set again (should fail because key exists)
490
created_again = r.json().set("profile:new_user", "$", profile_data, nx=True)
491
print(f"Profile created again: {created_again}")
492
493
# Update only if key exists (XX - eXists)
494
updated_data = {"username": "john_doe_updated"}
495
updated = r.json().set("profile:new_user", "$", updated_data, xx=True)
496
print(f"Profile updated: {updated}")
497
498
# Try to update non-existent key (should fail)
499
updated_missing = r.json().set("profile:missing", "$", updated_data, xx=True)
500
print(f"Missing profile updated: {updated_missing}")
501
```
502
503
### Bulk JSON Operations
504
505
```python
506
import redis
507
508
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
509
510
# Create multiple user profiles
511
users = [
512
{"id": 1001, "name": "Alice", "department": "Engineering"},
513
{"id": 1002, "name": "Bob", "department": "Sales"},
514
{"id": 1003, "name": "Carol", "department": "Marketing"}
515
]
516
517
# Use pipeline for bulk operations
518
pipe = r.pipeline()
519
520
for user in users:
521
pipe.json().set(f"employee:{user['id']}", "$", user)
522
523
results = pipe.execute()
524
print(f"Created {len(results)} employee profiles")
525
526
# Bulk retrieve specific fields
527
pipe = r.pipeline()
528
for user in users:
529
pipe.json().get(f"employee:{user['id']}", "$.name", "$.department")
530
531
employee_info = pipe.execute()
532
for info in employee_info:
533
print(f"Employee: {info}")
534
535
# Bulk update
536
pipe = r.pipeline()
537
for user in users:
538
pipe.json().set(f"employee:{user['id']}", "$.last_updated", "2024-01-15")
539
540
pipe.execute()
541
print("Updated all employee profiles")
542
```