4

How would one convert the following:

[{
  "name": "annoying data",
  "status": "evil",
  "frustration": [
   {
      "name": "foo",
      "value": 1
    },
    {
      "name": "bar",
      "value": 2
    },
    {
      "name": "baz",
      "value": 3
    }
  ]
}...]

To this output:

[{
  "name": "annoying data",
  "status": "evil",
  "foo": 1,
  "bar": 2,
  "baz": 3
}...]

from within a rethink query?

We have a stored third-party API response that I am attempting to transform into something useful. In my mind there are 2 things I need to accomplish to reach my end goal of sane data output.

  1. transform the frustration array into an object using name as the keys and value as the values.
  2. merge the newly transformed frustration object into the parent object.

I have a possible solution for step 2:

.map(function(row) {
    row.pluck('name', 'status').merge(row('frustration'))
})

But I'm getting nowhere with step one. Any ideas are much appreciated!

Current full query (names changed to protect... me!):

r.db('test').table('evil_things').map(function(row) {
  var x = row('a')('tree')('children')
        .nth(0)('children')
        .nth(0)
        .map(function(x) {
          return x('children');
        })
        .concatMap(function(x) {
          return x.pluck('name', 'value');
        })
  ;

  return {
    'name': row('name'),
    'status': row('status'),
    'frustration': x
  };
}).filter(function(row) {
  return r.expr(['FOO','BAR','BAZ']).contains(row('name').upcase());
})
.orderBy('status');

2 Answers 2

3

You are in correct way.

You can create an objects from a key-value list of data with object. But object receive a list of parameters, instead of an array so you need args.

frustation is an array with each document as object, you need a way to turn it into a list of flatten array, meaning from this array

[{key1: val1}, {key2: val2},...]

we turn it to

[key1, val1, key2, val2,...]

to feed into args for object. That's the job of concatMap.

Let's try this:

r.expr([{
  "name": "annoying data",
  "status": "evil",
  "frustration": [
    {
      "name": "foo",
      "value": 1
    },
    {
      "name": "bar",
      "value": 2
    },
    {
      "name": "baz",
      "value": 3
    }
  ]
}])
.map(function(doc) {
  return doc.pluck("name", "status").merge(
    r.object(r.args(doc('frustration')
     .concatMap(function(frustration) { return [frustration("name"), frustration("value")] })
    ))
  )
})

Result:

[
{
"bar": 2 ,
"baz": 3 ,
"foo": 1 ,
"name":  "annoying data" ,
"status":  "evil"
}
]

Hope it helps:

Sign up to request clarification or add additional context in comments.

2 Comments

awesome thank you for the push in the correct direction.
Hey Scull7, You can read more about this on this book(my book btw): github.com/kureikain/simplyrethink
2

Something like this should work:

.map(function(row) {
  return row.pluck('name', 'status').merge(
    row('frustration').map(function(x){ return [x['name'], x['value']]; }).coerceTo('object'))
})

1 Comment

That's awesome! Saved me so much time :) For javascript it has to be return [x('name'), x('value')]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.