AndersW
AndersW

Reputation: 48

Getting actual field value inside replace(function() {}) in RethinkDB

I am stuck trying to update to all entries I have saved in a RethinkDB table. Basically, I am trying to loop over all entries, read a property and save the processed result back to the same document as a new property.

I am using replace(function(entry) { return <object>}) as the key conversion piece.

Inside the replace function, entry.getField('fieldname') returns a function, not my stored value and this is where everything goes wrong.

What is the appropriate way to get the actual value from the document?

These lines from the function passed to replace is where it goes wrong

var ts = entry.getField('timestamp'); // Debugger says 'ts' is a Function!
var date = new Date(ts); // Fails because Date expects a string

The Full Code

/* Steps
 * 1 - Select all entries in DB.
 * 2 - For each entry
 *  2.1 - Read existing property 'timestamp' (format: '2015-05-06 15:04:48')
 *  2.2 - Convert to rethinkDB format and assign to new property 'timestampraw'
 *  2.3 - Replace entry
 */

var migrateDb = function migrateDb(r, conn, dbName, tableName) {
    r.db(dbName).table(tableName).limit(2)
        .replace(function (entry) {
            var ts = entry.getField('timestamp'); // 'ts' is a Function!?
            var date = new Date(ts); // This fails, because we are not passing in the actual property value
            entry.timestampraw = r.ISO8601(date, {defaultTimezone: '+02'});
            entry.converted = true;
            return entry;
        })
        .run(conn, {useOutdated: true, arrayLimit: 1000000}, function (err, res) {
            if (err) throw err;
            log(util.inspect(res));
        });
};


var r = require('rethinkdb');
r.connect(conf).then(function (conn) {
    migrateDb(r, conn, conf.db, conf.tableName);
});

Example data from the database

[{ id: '000264a9-63a3-4e8e-90b7-b1c256d79be3',
  name: 'waterLevel',
  timestamp: '2015-04-30 10:47:44',
  unit: 'cm',
  value: '14.1' 
},
{ id: '0000b44f-5754-498b-ba65-c79660f34618',
  name: 'pumpCurrent',
  raw: '-224',
  timestamp: '2015-05-06 15:04:48',
  unit: 'mA',
  value: 0
 }]

I have close to 500 000 values in the table, so that's why you see the limit() clause in the code example. Just want to experiment using a small subset.

I am using RethinkDB v2.0.1 from Node.js.

Upvotes: 0

Views: 342

Answers (1)

Jorge Silva
Jorge Silva

Reputation: 4614

I'm not sure why you're getting that that value is a function, but I don't think you can just run JavaScript inside the function. Keep in mind that in entry inside the replace function is not an JS object. It's a ReQL object.

How about trying the following:

var migrateDb = function migrateDb(r, conn, dbName, tableName) {
    r.db(dbName).table(tableName).limit(2)
        .replace(function (entry) {
            return entry.merge({
                // This is a way to get around ISO8601 date parsing
                // We're basically replacing a ' ' with 'T'
                'timestampraw' : r.ISO8601(
                    entry('timestamp').split()(0).add('T').add(entry('timestamp').split()(1)), 
                    {defaultTimezone: '+2' 
                }),
                'converted': true
            });
        })
        .run(conn, {useOutdated: true, arrayLimit: 1000000}, function (err, res) {
            if (err) throw err;
            log(util.inspect(res));
        });
};

Upvotes: 1

Related Questions