如何导入JSON并指定时间类型的JSON中的哪些字段?

时间:2014-10-19 18:51:32

标签: rethinkdb

我使用此命令将数据导入 RethinkDB

rethinkdb import --force -f ${folder}/json/data.json --table test.data -c localhost:28015

完美导入数据。但是我的json中有一些字段作为时间:

{
    "id": "1",
    "date": "2015-09-19",
    "time": {
        "begin": "09:00",
        "end": "10:30"
    }
}

当我试图查询这些字段时,例如data或time.begin,time.end将它们视为时间 - RethinkDB 并不理解它并抛出异常

r.db('test').table('data').filter(function(t) {
    return t("date").date()
})


RqlRuntimeError: Not a TIME pseudotype: `"2015-09-19"` in:
r.db("test").table("data").filter(function(var_43) { return var_43("date").date(); })
                                                                         ^^^^^^^^^^^^^^   

是否可以为RethinkDB指定JSON中哪个字段具有时间类型?

1 个答案:

答案 0 :(得分:3)

JSON没有提供指定时间字段的标准方法,但是有几种方法可以使用RethinkDB执行此操作:在插入数据之前或之后修改数据。 RethinkDB时间对象不仅仅是您在此处显示的字符串,还包含毫秒时间分辨率和时区数据。

可以使用r.now()r.time()r.epoch_time()r.ISO8601()构建时间对象。由于时间字符串的格式,我会使用r.ISO8601()。请务必注意,您的数据似乎不包含时区信息,因此如果数据全部放在同一时区,您应该确保数据不会返回错误的结果。

在RethinkDB中使用时间时要记住的另一件事是数据将在客户端中转换为适当的时间对象。由于您似乎正在使用Javascript,因此您将获得一个Date对象。对于Python,您将获得一个datetime.datetime对象等。如果您希望获得原始时间假型格式(请参见下文),您可以将timeFormat: "raw"指定为查询的全局optarg(请参阅文档详情请参阅run()

对RethinkDB中的数据进行后处理

这可能是最简单的选择,我会推荐。导入数据后,可以运行查询来修改每一行,将字符串转换为时间对象。根据您的数据格式,这应该有效:

r.db('test').table('data').replace(function(row) {
    return row.merge({
        'begin_time': r.ISO8601(row('date').add('T').add(row('time')('begin')), { defaultTimezone: '+00:00' }),
        'end_time': r.ISO8601(row('date').add('T').add(row('time')('end')), { defaultTimezone: '+00:00' })
        }).without('date', 'time');
    }).run(conn, callback)

这会将date表格中所有行的timetest.data字段替换为可用作您的begin_timeend_time时间对象期望。 defaultTimezone字段是必需的,因为时间字符串不包含时区信息,但您应将这些值更改为适当的值。

修改JSON数据

这是一个较低级别,可能很棘手,但如果你不介意弄脏手,这可能更适合你的需要。

RethinkDB时间对象使用特定格式以JSON形式进行通信,以表示“假型”'。这些是JSON中未标准化的类型,仍存在于RethinkDB中。时间假型的格式如下所示:

{
    "$reql_type$": "TIME",
    "epoch_time": 1413843783.195,
    "timezone": "+00:00"
}

其中epoch_time是自UNIX纪元(1970年1月1日)以来的秒数。如果要导入的数据遵循此格式,则可以直接插入,并且数据库将其解释为有效的时间对象。您可以自行修改要导入的数据,但您的示例行看起来像这样:

{
    "id": "1",
    "begin_time": {
        "$reql_type$": "TIME",
        "epoch_time": 1442653200,
        "timezone": "+00:00"
    },
    "end_time': {
        "$reql_type$": "TIME",
        "epoch_time": 1442658600,
        "timezone": "+00:00"
    }
}

同样适用于时区的警告也适用于此。