Поскольку вы пометили этот вопрос Meteor, я полагаю, у вас есть среда Meteor по умолчанию, в которой вы можете использовать легкие коллекции Mongo на стороне клиента .
Это дает вам возможностьПубликация (публикация) / возврат (метод) ваших данных в основном не отсортированы, и пусть клиент справится с этой задачей.
Подумайте так: всего 100 клиентов запрашивают публикацию, которая обновляется при каждом действии сортировки (поскольку параметры подписки изменяются,поэтому публикация тоже меняется).
Это приводит к тому, что ваш сервер уже использует большой объем ОЗУ, чтобы наблюдатели (OPLOG и т. д.) работали для 100 публикаций, каждая из которых запрашивает огромное количество документов.
Возможные эффективные решения описаны ниже.Пожалуйста, имейте в виду, что они не связаны ни с каким интерфейсом, а скорее с концептуальным описанием.Вы должны будете включить реактивность и т. Д. В зависимости от вашей внешней среды.
Вариант A - Публикация несортированных, пусть клиенты сортируют
сервер
Meteor.publish('hugeData', function () {
return MyCollection.find({ ...})
})
client
const handle = Meteor.subscribe('hugeData')
if (handle.ready()) {
const sortedData = MyCollection.find({ ... }, {sort: { someField: -1 } })
}
Большой плюс в том, что вы можете информировать клиентов о статусе полноты, если используете cursor.observeChanges
.
Обратите внимание, что если вы хотите сканировать в обратном направлении (возвратите документы, с самыми новыми), вы можете использовать опцию hint
при поиске :
Meteor.publish('hugeData', function () {
return MyCollection.find({ ...}, { hint: { $natural : -1 })
})
Это гораздо большес производительностью, превышающей { sort: { fieldName: -1} }
.
Опция B - вернуть несортированный из метода, разрешить клиентам сортировать
Теперь все еще может быть проблема с решением A, так как он все еще имеет много оперативной памяти для потребленияесли есть много подписчиков.Альтернатива (особенно если изменения данных в реальном времени не так важны) заключается в использовании метеорных методов:
сервер
Meteor.method('hugeData', function () {
return MyCollection.find({ ...}).fetch()
})
Обратите внимание, что для этого требуется fetch
документы, в противном случае и unhandledPromiseRejection
выбрасывается.
клиент
Для этого требуется LocalCollection
на клиенте, то есть не синхронизирован с вашей коллекцией на стороне сервера, или у вас возникнут проблемы с синхронизацией документов:
const HugeData = new LocalCollection(null) // note the null as collection name!
const insertUpdate = document => {
if (LocalCollection.findOne(document._id)) {
delete document._id
return LocalCollection.update(document._id, document)
} else {
return LocalCollection.insert(document)
}
}
Meteor.call('hudeData', (err, data) => {
data.forEach(insertUpdate)
})
Затем вы можете использовать LocalCollection
на клиенте для любой проекции полученных данных.
В целом, это хороший компромисс для переноса нагрузки на клиентов.Пока вы держите их в курсе, когда прогнозирование занимает некоторое время, все должно быть в порядке.