У меня есть RethinkDB с таблицей 'events', каждое событие имеет столбцы 'from' и 'to', обе являются временными метками.
Я хочу в основном запросить эту таблицу, возвращая все события, которые являются «активными» во временном окне, то есть столбец с находится перед концом временного окна, а конечный столбец - после начала временного окна (начало временного окна является текущим временем, а конец временное окно текущее время + 2 часа). По этой причине я создал вторичный индекс для обоих столбцов.
В идеале мне бы хотелось получать его в виде единого канала изменений, включающего любые изменения в событиях в реальном времени, а также выбирать события, которые становятся активными по мере продвижения времени , но из того, что я могу сказать, это невозможно, так как в соответствии с документами «Команда now () вычисляется один раз, когда сервер получает запрос» (исправьте меня, если я ошибаюсь), поэтому я прибегну к созданию нового changefeed каждый час, который запрашивает активные события в 2-часовом окне от текущего времени.
Теперь я сначала подумал, что буду использовать два между вызовами, например, так:
let currentEndpoint = moment().add(2, 'hours');
// query for active events
r
.table('events')
// event start is before end of window
.between(new Date(1), currentEndpoint, {index: 'from'})
// event end is after current time
.between(new Date(), r.epochTime(1900266776))
.run(connection)
.then(res => {
console.log(res)
})
.catch(e => {
console.error(e);
})
Что, по-видимому, не разрешено : ReqlQueryLogicError: Cannot perform multiple BETWEENs on the same tabl
Я понимаю, как можно было бы сделать это с помощью команды фильтра довольно легко, но, поскольку это основной способ запроса таблицы, я подумал, что было бы лучше использовать индексы, Есть ли способ создать этот запрос?
Визуальный пример
event2
\
_____\______
/ \
time: ---->---->---->---->---->---->---->---->---->---->----> ...
\__/ \__/ / \__/
event1___/ event3__/ / event5__/
event4_/
^ ^
query window: |______________|
expected results: [ event2, event3 ]
Воспроизводимая задача
Создание таблицы events
-
r.tableCreate("events");
// { tables_created: 1, ... }
Добавить некоторые события. Для простоты концептуального подхода мы заботимся только о year
, month
и day
. Решение проблемы для более детального времени, такого как hours
или minutes
, фактически совпадает
r.table("events").insert([
{ name: "fishing tourney"
, from: r.time(2020, 1, 11, "Z")
, to: r.time(2020, 1, 12, "Z")
}
, { name: "cherry blossom"
, from: r.time(2020, 4, 1, "Z")
, to: r.time(2020, 4, 10, "Z")
}
, { name: "fishing tourney"
, from: r.time(2020, 4, 11, "Z")
, to: r.time(2020, 4, 12, "Z")
}
, { name: "bunny day"
, from: r.time(2020, 4, 1, "Z")
, to: r.time(2020, 4, 12, "Z")
}
, { name: "fishing tourney"
, from: r.time(2020, 7, 11, "Z")
, to: r.time(2020, 7, 12, "Z")
}
]);
// { inserted: 5, generated_keys: [ ... ], ... }
Создайте некоторый вторичный индекс -
r.table("events").indexCreate(
"event_window",
???
);
При заданном диапазоне дат получить все события с пересекающимся окном событий -
const start = r.time(2020, 4, 8, "Z"); // April 8, 2020
const end = start.add(3 * 24 * 60 * 60); // April 11, 2020, 3 days later
// filter it?
r.table("events").filter(???)...
// use .between somehow?
r.table("events").between(???, ???, { index: "event_window" })
// some other technique?
r.table("events").eqJoin(???)
r.table("events").???
Перекрытия событий 8 апреля 2020 г. - 11 апреля 2020 г. -
// expected output
[ { name: "cherry blossom"
, from: r.time(2020, 4, 1, "Z")
, to: r.time(2020, 4, 10, "Z")
}
, { name: "fishing tourney"
, from: r.time(2020, 4, 11, "Z")
, to: r.time(2020, 4, 12, "Z")
}
]