Saturday, October 15, 2022

Redis + Mongo Document (JSON/Search) Commands Comparison

Summary

This post will demonstrate equivalent Create, Read, Update and Delete (CRUD) commands in MongoDB and Redis.  I provide examples from Mongo's shell (mongosh), Redis CLI, node-redis client lib, and redis-py client lib.

Sample Data Set

Below is a snippet of the JSON document that is used in all the examples.

  1. [
  2. {
  3. "item": "journal",
  4. "qty": 25,
  5. "tags": ["blank", "red"],
  6. "dim_cm": [ 14, 21 ],
  7. "size": {
  8. "h": 14,
  9. "w": 21,
  10. "uom": "cm"
  11. },
  12. "status": "E"
  13. },
  14. {
  15. "item": "notebook",
  16. "qty": 50,
  17. "tags": ["red", "blank"],
  18. "dim_cm": [ 14, 21 ],
  19. "size": {
  20. "h": 14,
  21. "w": 21,
  22. "uom": "cm"
  23. },
  24. "status": "E"
  25. },

Create Operation

Mongo Shell

  1. db.inventory.insertMany([
  2. { _id: 1, item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ], size: { h: 14, w: 21, uom: "cm" }, status: "E" },
  3. { _id: 2, item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ], size: { h: 14, w: 21, uom: "cm" }, status: "E" },
  4. { _id: 3, item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ], size: { h: 19, w: 22.85, uom: "cm" },status: "B" },
  5. { _id: 4, item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ], status: "C" },
  6. { _id: 5, item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ], status: "D" }
  7. ])
  8.  
  9. db.inventory.createIndexes([
  10. {qty: 1},
  11. {item: 1},
  12. {tags: 1},
  13. {size: 1},
  14. {status: 1}
  15. ])

Redis CLI

  1. JSON.SET inventory:1 . '{"item":"journal","qty":25,"tags":["blank","red"],"dim_cm":[14,21],"size":{"h":14,"w":21,"uom":"cm"},"status":"E"}'
  2. JSON.SET inventory:2 . '{"item":"notebook","qty":50,"tags":["red","blank"],"dim_cm":[14,21],"size":{"h":14,"w":21,"uom":"cm"},"status":"E"}'
  3. JSON.SET inventory:3 . '{"item":"paper","qty":100,"tags":["red","blank","plain"],"dim_cm":[14,21],"size":{"h":19,"w":22.85,"uom":"cm"},"status":"B"}'
  4. JSON.SET inventory:4 . '{"item":"planner","qty":75,"tags":["blank","red"],"dim_cm":[22.85,30],"status":"C"}'
  5. JSON.SET inventory:5 . '{"item":"postcard","qty":45,"tags":["blue"],"dim_cm":[10,15.25],"status":"D"}'
  6.  
  7. FT.CREATE inventoryIdx ON JSON PREFIX 1 inventory: SCHEMA $.item AS item TEXT $.qty AS qty NUMERIC $.tags.* AS tags TAG $.dim_cm[0] AS dim_cm_0 NUMERIC $.dim_cm[1] AS dim_cm_1 NUMERIC $.status AS status TEXT $.size.h AS sizeh NUMERIC $.size.w AS sizew NUMERIC $.size.uom AS sizeuom TEXT

node-redis (Javascript)

  1. for (let item of dataset) {
  2. await client.json.set(`inventory:${itemNum++}`, '.', item);
  3. }
  4. await client.ft.create('inventoryIdx', {
  5. '$.item': {
  6. type: SchemaFieldTypes.TEXT,
  7. AS: 'item'
  8. },
  9. '$.qty': {
  10. type: SchemaFieldTypes.NUMERIC,
  11. AS: 'qty'
  12. },
  13. '$.tags.*': {
  14. type: SchemaFieldTypes.TAG,
  15. AS: 'tags'
  16. },
  17. '$.dim_cm[0]': {
  18. type: SchemaFieldTypes.NUMERIC,
  19. AS: 'dim_cm_0'
  20. },
  21. '$.dim_cm[1]': {
  22. type: SchemaFieldTypes.NUMERIC,
  23. AS: 'dim_cm_1',
  24. },
  25. '$.status': {
  26. type: SchemaFieldTypes.TEXT,
  27. AS: 'status'
  28. },
  29. '$.size.h': {
  30. type: SchemaFieldTypes.NUMERIC,
  31. AS: 'sizeh'
  32. },
  33. '$.size.w': {
  34. type: SchemaFieldTypes.NUMERIC,
  35. AS: 'sizew'
  36. },
  37. '$.size.uom': {
  38. type: SchemaFieldTypes.TEXT,
  39. AS: 'sizeuom'
  40. }
  41. }, {
  42. ON: 'JSON',
  43. PREFIX: 'inventory:'
  44. });

redis-py (Python)

  1. itemNum = 1
  2.  
  3. for dataItem in dataset:
  4. client.json().set(f'inventory:{itemNum}', '.', dataItem)
  5. itemNum += 1
  6.  
  7. index_def = IndexDefinition(
  8. index_type=IndexType.JSON,
  9. prefix=['inventory:']
  10. )
  11. schema = ( TextField('$.item', as_name='item'),
  12. NumericField('$.qty', as_name='qty'),
  13. TagField('$.tags.*', as_name='tags'),
  14. NumericField('$.dim_cm[0]', as_name='dim_cm_0'),
  15. NumericField('$.dim_cm[1]', as_name='dim_cm_1'),
  16. TextField('$.status', as_name='status'),
  17. NumericField('$.size.h', as_name='sizeh'),
  18. NumericField('$.size.w', as_name='sizew'),
  19. TextField('$.size.uom', as_name='sizeuom')
  20. )
  21. client.ft('inventoryIdx').create_index(schema,definition=index_def)

Read Operation - Compound Query

Mongo Shell

  1. db.inventory.find( {
  2. status: "E",
  3. $or: [ { qty: { $lt: 30 } }, { item: /^pa/ } ]
  4. } )

Redis CLI

  1. FT.SEARCH inventoryIdx '(@status:E) ((@qty:[-inf (30])|(@item:pa*))'

node-redis (Javascript)

  1. await client.ft.search('inventoryIdx', '(@status:E) ((@qty:[-inf (30])|(@item:pa*))');

redis-py (Python)

  1. client.ft('inventoryIdx').search(Query('(@status:E) ((@qty:[-inf (30])|(@item:pa*))')).docs

Update Operation

Mongo Shell

  1. db.inventory.update(
  2. { _id: 2 },
  3. {
  4. $inc: { qty: 5 },
  5. $set: {
  6. item: "spiral notebook",
  7. }
  8. }
  9. )

Redis CLI

  1. MULTI
  2. JSON.NUMINCRBY inventory:2 '.qty' 5
  3. JSON.SET inventory:2 .item '"spiral notebook"'
  4. EXEC

node-redis (Javascript)

  1. await client
  2. .multi()
  3. .json.numIncrBy('inventory:2', '.qty', 5)
  4. .json.set('inventory:2', '.item', 'spiral notebook' )
  5. .exec();

redis-py (Python)

  1. pipe = client.pipeline()
  2. pipe.json().numincrby('inventory:2', '.qty', 5)
  3. pipe.json().set('inventory:2', '.item', 'spiral notebook')
  4. pipe.execute()

Delete Operation

Mongo Shell

  1. db.inventory.deleteOne( { "_id" : 2 } )

Redis CLI

  1. JSON.DEL inventory:2

node-redis (Javascript)

  1. await client.json.del('inventory:2');

redis-py (Python)

  1. client.json().delete('inventory:2')

Source (with more examples)

https://github.com/Redislabs-Solution-Architects/docdevdemo

Copyright ©1993-2024 Joey E Whelan, All rights reserved.