Запрос 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')
Надеюсь, это поможет.