Очевидно, что это старый вопрос, но я столкнулся с ним, когда исследовал MongoDB для данных временных рядов. Я подумал, что, возможно, стоит поделиться следующим подходом для предварительного выделения полных документов и выполнения операций обновления, в отличие от новых операций вставки. Обратите внимание, что этот подход был задокументирован здесь и здесь .
Представьте, что вы храните данные каждую минуту. Рассмотрим следующую структуру документа:
{
timestamp: ISODate("2013-10-10T23:06:37.000Z"),
type: ”spot_EURUSD”,
value: 1.2345
},
{
timestamp: ISODate("2013-10-10T23:06:38.000Z"),
type: ”spot_EURUSD”,
value: 1.2346
}
Это сопоставимо со стандартным реляционным подходом. В этом случае вы создаете один документ на каждое записанное значение, что вызывает много операций вставки. Мы можем сделать лучше. Учтите следующее:
{
timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"),
type: “spot_EURUSD”,
values: {
0: 1.2345,
…
37: 1.2346,
38: 1.2347,
…
59: 1.2343
}
}
Теперь мы можем написать один документ и выполнить 59 обновлений. Это намного лучше, потому что обновления являются атомарными, отдельные записи меньше, и есть другие преимущества производительности и параллелизма. Но что, если бы мы хотели хранить весь день, а не только все часы, в одном документе. Это тогда потребовало бы, чтобы мы пошли вдоль 1440 записей, чтобы получить последнее значение. Чтобы улучшить это, мы можем расширить до следующего:
{
timestamp_hour: ISODate("2013-10-10T23:00:00.000Z"),
type: “spot_EURUSD”,
values: {
0: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343},
1: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343},
…,
22: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343},
23: { 0: 1.2343, 1: 1.2343, …, 59: 1.2343}
}
}
Используя этот вложенный подход, теперь нам нужно только пройти максимум 24 + 60, чтобы получить самое последнее значение в день.
Если мы создаем документы со всеми значениями, заполненными заранее заполнением, мы можем быть уверены, что документ не изменит размер и, следовательно, не будет перемещен.