在 RethinkDB 中获取 replace(function() {}) 中的实际字段值

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

我无法尝试更新我保存在 RethinkDB 中的所有条目 table。基本上,我试图遍历所有条目,读取 属性 并将处理后的结果保存回与新 属性.

相同的文档

我正在使用replace(function(entry) { return <object>})作为密钥转换部分。

在替换函数中,entry.getField('fieldname') returns 一个函数,而不是我的存储值,这就是一切出错的地方。

从文档中获取实际值的合适方法是什么?

传递给replace的函数中的这些行就是出错的地方

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

完整代码

/* 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);
});

来自数据库的示例数据

[{ 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
 }]

我在 table 中有接近 500 000 个值,所以这就是您在代码示例中看到 limit() 子句的原因。只想使用一小部分进行实验。

我正在使用来自 Node.js 的 RethinkDB v2.0.1。

我不确定您为什么认为该值是一个函数,但我认为您不能只 运行 JavaScript 在函数内部。请记住,在 entry 里面的 replace 函数不是 JS 对象。它是一个 ReQL 对象。

尝试以下方法如何:

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));
        });
};