Вам придется использовать некоторый код:
(я вижу, вы используете mongoose
, поэтому я пишу это с синтаксисом mongoose
)
const aggregate = Model.aggregate([{ $sample: { size: size } }]);
const aggregate2 = Model.aggregate([
{ $match: { _id: {$nin: aggregated.map(val => val._id)}}},
{ $sample: { size: size } }
]);
Обратите внимание, что это необходимо второй конвейер до первого $match
всего сбора за вычетом объема выборочных данных. это может быть очень неэффективно.
В зависимости от вашей шкалы я рекомендую добавить некоторые эвристики, например, допустим, что размер выборки равен x
, и у нас есть y
документов в дБ.
Я бы использовал что-то как следующий конвейер:
const aggregate = Model.aggregate([{ $sample: { size: x } }]);
const aggregate2 = Model.aggregate([
{ $sample: { size: 2x } }
{ $match: { _id: {$nin: aggregated.map(val => val._id)}}},
{ $limit: x }
]);
Вы можете повозить числа (2x - верхний предел, но в зависимости от размера вашего набора данных он может быть понижен с высокой вероятностью успеха), это позволит вам получить x уникальные документы и во втором конвейере при использовании извлечения индекса $sample
.
Все это предполагает, что вы соответствуете условиям $ sample для использования индекса:
$ образец является первой ступенью конвейера
N составляет менее 5% от общего количества документов в коллекции
Коллекция содержит более 100 документов