redis / node-redis

Redis Node.js client

Home Page:https://redis.js.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Return redisgraph data without mapping it to objects

jonaskello opened this issue · comments

Motivation

Redisgraph data is first returned as an array of arrays. But inside the graph module it is then remapped to objects:

https://github.com/redis/node-redis/blob/master/packages/graph/lib/graph.ts#L233

I think it would be nice if the caller can decide if the cost of mapping to objects is needed. Basically I would prefer if the original format for GraphReply with just arrays was returned and then I could do any mapping outside if needed.

Basic Code Example

const result = await graph.roQuery(
  'MATCH (r:Rider)-[:rides]->(t:Team { name: $name }) RETURN r.name AS name',
  {
    params: {
      name: 'Apollo'
    }
  }
);

// result will always be an array of objects, would prefer the original redis reply format of array or arrays to be retained

What do you mean by raw reply? The Graph class uses the compact mode, so the raw results are not very useful (without at least resolving the "metadata", which requires some parsing)..

const result = await graph.roQuery(
  'MATCH (r:Rider)-[:rides]->(t:Team { name: $name }) RETURN r.name AS name',
  {
    params: {
      name: 'Apollo'
    }
  },
  {
    rawReply: true
  }
);

How do you expect the result from the code above to look?

BTW, you can use client.graph.query/client.graph.roQuery directly..

Yes, support for compact mode is actually why we want to use this package :-). To give some background, we're currently using ioredis with an extra layer on top for parsing GRAPH.QUERY but the work you have done here with compact mode seems like a much better solution.

So to explain a bit more, I did not mean the raw result from compact mode, just that the resulting rows would be an array of tuples, instead of an array of objects. So I don't think we're looking for a rawReply option.

For this call:

const result = await graph.roQuery(
  'MATCH (r:Rider)-[:rides]->(t:Team { name: $name }) RETURN r.name AS name',
  {
    params: {
      name: 'Apollo'
    }
  }
);

I would expect the result to be:

{
  metadata: [
    "Cached execution: 1",
    "Query internal execution time: 0.469832 milliseconds"
  ],
  headers: [name],
  data: [
     ["Somename"],
     ["Someothername"]
  ]
}

Today we are currently getting

{
  metadata: [
    "Cached execution: 1",
    "Query internal execution time: 0.469832 milliseconds"
  ],
  data: [
     {name: "Somename"},
     {name: "Someothername"}
  ]
}

One reason for having the data fields as an array of tuples would be that it is more compact if you want to serialize as JSON.

Ok, makes sense now, so something like:

const result = await graph.roQuery(
  'MATCH (r:Rider)-[:rides]->(t:Team { name: $name }) RETURN r.name AS name',
  {
    params: {
      name: 'Apollo'
    }
  },
  {
    replyAs: Object/Map/Array
  }
);

// with Object (or by default)
{
  metadata: ...,
  data: [
     { name: 'name' },
  ]
}

// with Map
{
  metadata: ...,
  data: [
     new Map({ name: 'name' })
  ]
}

// with Array
{
  metadata: ...,
  data: [
    ['name, 'name']
  ]
}

@guyroyse @simonprickett WDUT?