Search code examples
node.jsmongodbexpressredisbson

Complex data structures in Redis


I am refactoring the backend of a Node/Express app from MongoDB to Redis.

My data currently consist of a few dozen (~70) documents, each composed of a NAME, an abbreviation ABBR, a GeoJSON LOCATION, and an array of integer PARAMETERs. The PARAMETERs for each document are updated every few minutes, but the rest of the attributes remain fixed. The length of the PARAMETER attribute may vary (and it can also be empty). I would like to perform many queries on the data to check the nearest locations to a given point, and display the name, the abbreviation, and the parameters.

An example document:

{ 
  _id: ObjectId("1"), 
  name: 'A place', 
  abbr: 'PLC', 
  location: { type: "Point", coordinates: [ -130.922, 33.289 ]},
  parameters: [3 4 28],
 }

I am familiar with the GEOADD command in Redis, but I don't see how to use it to create a more complex data structure to hold my data given that if I use the GEOADD command to specify a location and then attempt to use HMSET to add fields for name and abbreviation, I obtain a WRONGTYPE error.

I appreciate the error because I value referential transparency and I like when types are taken seriously. But I also think I might be fundamentally misunderstanding how Redis stores data. When I originally began refactoring after learning about Redis conceptually, I envisioned being able to store my data in a form something like

1 name 'A Place' abbr 'PLC' location -130.922 33.289 parameters 3 4 28

Or if not quite that, a way to easily query the nearness of locations in my set along with the other attributes.


Solution

  • Redis core data structures can not be nested. In your example you should use different a different key (and data structure) for each level, e.g. a Hash for the properties, a Geoset for the location and a perhaps another Hash for the parameters.

    Once you have that in place, your query should consist of three reads to compose the final answer.