按日期分组的 RethinkDB 查询

RethinkDB query with group by date

我存储了以下文档:

{
    "date": 1437429603126,
    "id": "7c578fe6-5eeb-466c-a79a-628784fd0d16",
    "quote": {
        "c": "+2.45",
        "c_fix": "2.45",
        "ccol": "chg",
        "cp": "1.89",
        "cp_fix": "1.89",
        "div": "0.52",
        "e": "NASDAQ",
        "ec": "+0.58",
        "ec_fix": "0.58",
        "eccol": "chg",
        "ecp": "0.44",
        "ecp_fix": "0.44",
        "el": "132.65",
        "el_cur": "132.65",
        "el_fix": "132.65",
        "elt": "Jul 20, 5:59PM EDT",
        "id": "22144",
        "l": "132.07",
        "l_cur": "132.07",
        "l_fix": "132.07",
        "lt": "Jul 20, 4:09PM EDT",
        "lt_dts": "2015-07-20T16:09:40Z",
        "ltt": "4:09PM EDT",
        "pcls_fix": "129.62",
        "s": "2",
        "t": "AAPL",
        "yld": "1.57"
    }
}

并查看 运行 选择字段 quote.tquote.lquote.cquote.cp 的查询,其中 tAAPLdate 排序。缺少的部分是在同一天按多个文档分组。我需要的逻辑是获取最旧的文档 quote.t = AAPL。所以基本上每天应该只返回一个文档,并且那个文档应该有最大的 date.

到目前为止,这是我所拥有的,但在一天内缺少对多个文档的分组。

r.db('macd').table('daily_closes').filter({
    'quote': {
        't': 'AAPL'
    }
}).orderBy('date').pluck('date', {
    'quote': [
        't',
        'l',
        'c',
        'cp'
    ]
})

此外,我有二级索引,如何在查询中使用它们?

您需要按日期分组,但您将日期存储为纪元时间。所以你需要一种方法把它变成天和组。然后我们可以 group 按该值,并按 desc 顺序对归约数组进行排序,然后使用 nth 获取该数组的第一个元素。

r.table('daily_closes').filter({
    'quote': {
        't': 'AAPL'
    }
}).orderBy('date')
.pluck('date', {
    'quote': [
        't',
        'l',
        'c',
        'cp'
    ]
}).group(r.epochTime(r.row('date').div(1000)).date()).orderBy(r.desc('date')).nth(0)

你可能得到这样的结果:

{
"group": Mon Jul 20 2015 00:00:00 GMT+00:00 ,
"reduction": {
"_date": Mon Jul 20 2015 00:00:00 GMT+00:00 ,
"date": 1437429603126 ,
"quote": {
"c":  "+2.45" ,
"cp":  "1.89" ,
"l":  "132.07" ,
"t":  "AAPL"
}
}
}

所以让我们减少噪音,我们会 ungroup 它。基本上没有ungroup,你是在对每个组的子流进行操作,当你ungroup,它们就变成了一个文件。我们也只关心 reduction 中的数据,因为它包含单个第一个文档。这是最终查询:

r.table('daily_closes').filter({
    'quote': {
        't': 'AAPL'
    }
}).orderBy('date')
.pluck('date', {
    'quote': [
        't',
        'l',
        'c',
        'cp'
    ]
})
.group(r.epochTime(r.row('date').div(1000)).date()).orderBy(r.desc('date')).nth(0)
.ungroup()
.getField('reduction')

现在,让我们使用索引。

首先,filter很慢,而且限制在100k文档,order没有索引很慢。让我们切换到带有索引的 getAll。但是我们不能 order 后跟 getAll 的索引。所以我们将使用这个技巧:

为值和使用创建索引 between:

r.table('daily_closes').indexCreate('quote_date', [r.row('quote')('t'),r.row('date')])

现在,我们使用 between:

r.table('daily_closes')
.between(['AAPL', r.minval], ['AAPL', r.maxval],{index: 'quote_date'})
.pluck('date', {
    'quote': [
        't',
        'l',
        'c',
        'cp'
    ]
})
.group(r.epochTime(r.row('date').div(1000)).date())
.orderBy(r.desc('date')).nth(0)
.ungroup()
.getField('reduction')

希望对您有所帮助。