Запрос RethinkDB с группировкой по дате

У меня хранятся следующие документы:

{
    "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.t, quote.l, quote.c, quote.cp где t является AAPL Сортировать по date, Часть, которая отсутствует, группируется по нескольким документам в один и тот же день. Логика мне нужна это взять самый старый документ, где quote.t = AAPL, Таким образом, в основном должен быть только один документ, возвращаемый каждый день, и этот документ должен иметь наибольшее date,

Вот то, что я имею до сих пор, пропуская группировку нескольких документов за один день.

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

Кроме того, у меня есть вторичные индексы, как я могу использовать их в запросе?

1 ответ

Решение

Вам нужно сгруппировать по дате, но вы храните день как время эпохи. Таким образом, вам нужен способ превратить его в день и группу. Мы можем тогда group по этому значению и отсортируйте массив редукций в порядке убывания, затем получите первый элемент этого массива с 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 медленно, и ограничить до 100 КБ документа, order без индекса медленно. Давайте переключимся на getAll с индексом. Но мы не можем order с индексом, сопровождаемым getAll, Итак, мы будем использовать этот трюк:

Создать индекс для значения и использования between:

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

Теперь мы используем между:

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')

Надеюсь, это поможет.

Другие вопросы по тегам