Я внедряю социальные функции в приложение стека MERN (отслеживание / отмена подписки) и пытаюсь найти хорошее решение MongoDB для избежания проблем с потенциально большими неограниченными массивами подписчиков. В частности, я надеюсь избежать:
- MongoDB, чтобы перемещать большой массив подписчиков на диск и перестраивать индексы по мере его увеличения
- , превышая предел 16 МБс по Бсону, если пользователь когда-либо достигнет очень большое количество подписчиков (> 1 миллион)
- низкая производительность при запросе / возврате подписчиков для отображения через нумерацию страниц или при расчете / отображении количества подписчиков
Из всего, что есть в Iv'e исследовано, кажется, что использование подхода с использованием шаблона ведра является лучшим решением ... две хорошие статьи, которые я нашел по этому вопросу: https://www.mongodb.com/blog/post/paging-with-the-bucket-pattern--part-1 https://www.mongodb.com/blog/post/paging-with-the-bucket-pattern--part-2
I Мы начали подходить к этому следующим образом ... Модель подписчика:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const FollowerSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: 'user',
},
// creating an array of followers
followers: [
{
user: {
type: Schema.Types.ObjectId,
ref: 'user',
},
datefol: {
type: Date,
default: Date.now,
},
},
],
count: {
type: Number,
},
createdate: {
type: Date,
default: Date.now,
required: true,
},
});
module.exports = Follower = mongoose.model('follower', FollowerSchema);
Вставить в Node.js API, чтобы добавить подписчика в корзину массива (каждая корзина будет содержать 100 подписчиков):
const follow = await Follower.updateOne(
{ user: req.params.id, count: { $lt: 100 } },
{
$push: {
followers: {
user: req.user.id,
datefol: Date.now(),
},
},
$inc: { count: 1 },
$setOnInsert: { user: req.params.id, createdate: Date.now() },
},
{ upsert: true }
);
Обычно каждый раз, когда добавляется подписчик, он добавляет их к первому найденному сегменту, который содержит менее 100 подписчиков (отслеженных по количеству).
Является ли это лучшим подходом для обработки потенциальных ли большие массивы? Я обеспокоен тем, что:
- , если кто-то отменит подписку пользователя и приложение запускает $ pull, чтобы удалить подписчика из массива в одном из сегментов ... тогда несколько блоков могут содержать менее 100 подписчиков. Новые подписчики больше не будут добавляться в самое последнее ведро, поэтому позже, при запросе и попытке вернуть подписчиков, основываясь на самых последних созданных корзинах ... некоторые из новейших подписчиков могут быть в более старом корзине и возвращаться неправильно. В вышеприведенных статьях упоминаются некоторые выразительные инструкции по обновлению, представленные в MongoDb 4.2, которые решают эту проблему, но мне не совсем понятно, как.
- , если я исправлю это, возвращая все корзины последователей для пользователя и сортируя по дате следования ... кажется, что это может стать очень медленным, если у кого-то будет тонна подписчиков
- , если я хочу иметь возможность разбивать на страницы и возвращать 100 подписчиков на страницу, начиная с последней, как это будет работать с таким подходом ? Должен ли я добавить запись номера страницы в модель и каким-то образом увеличивать ее при каждом создании корзины (первая корзина содержит номер страницы 1, следующая страница 2 и т. Д. c), а затем на переднем конце, если пользователь переходит на страницу подписчика 500 выполняется запрос, чтобы вытащить корзину 500?