Я работал с mongodb, но совершенно новым для mongoose ORM. Я пытался получить данные из коллекции, а вывод explain() показывал 50 мс. общее время, затрачиваемое на получение данных через мангуст, составляло 9 секунд. Вот запрос:конвертировать поток мангуста в массив
Node.find({'dataset': datasetRef}, function (err, nodes){
// handle error and data here
});
Затем я применил индекс в поле, на которое я запрашивал. Теперь результат explain() показал 4 мс. Но общее время для извлечения данных через мангуста не изменилось. Тогда я искал немного, и обнаружил, что использование мяса() может помочь принести производительность запросов на чтении в мангусте довольно близко к родному MongoDB
Так что я изменил мой запрос:
Node.find({'dataset': datasetRef})
.lean()
.stream({transform: JSON.stringify})
.pipe(res)
Это решило проблему с производительностью полностью. Но конечный результат представляет собой поток JSON документы, как это:
{var11: val11, var12: val12}{var21: val21, var22: val22} ...
Как разобрать это, чтобы сформировать массив документации? Или я не должен использовать поток вообще? По-моему, нет смысла использовать поток, если я планирую сформировать массив на бэкэнд, так как мне придется ждать, пока все документы будут считаны в памяти. Но я также думаю, что разбор и создание всего массива на лицевой стороне может оказаться дорогостоящим.
Как добиться максимальной производительности в этом случае, не забивая сеть?
UPDATE
Я пытаюсь решить эту проблему с помощью сквозного потока. Тем не менее, я не могу вставлять запятые между объектами JSON. Смотрите код ниже:
res.write("[");
var through = require('through');
var tr = through(
function write(data){
this.queue(data.replace(/\}\{/g,"},{"));
}
);
var dbStream = db.node.find({'dataset': dataSetRef})
.lean()
.stream({'transform': JSON.stringify});
dbStream.on("end", function(){
res.write("]");
});
dbStream
.pipe(tr)
.pipe(res);
С этим я могу получить «[» в начале и «]» в конце. Тем не менее, все еще не удается получить patten "} {" replace with "}, {". Не уверен, что я делаю неправильно
UPDATE 2
Теперь понял, почему заменить не работает. Похоже, что, поскольку я определил функцию преобразования как JSON.stringify, он читает один объект JSON за раз и, следовательно, никогда не сталкивается с шаблоном }{
, так как он никогда не выбирает несколько элементов JSON за раз.
Теперь я изменил свой код и написал пользовательскую функцию преобразования, которая делает JSON.stringify, а затем добавляет запятую в конце. Единственная проблема, с которой я столкнулся, заключается в том, что я не знаю, когда это последний объект JSON в потоке. Потому что я не хочу добавлять запятую в этом случае. В настоящий момент я добавляю пустой объект JSON после того, как встречается конец. Но почему-то это не похоже на убедительную идею. Вот код:
res.write("[");
function transform(data){
return JSON.stringify(data) + ",";
}
var dbStream = db.node.find({'dataset': dataSetRef})
.lean()
.stream({'transform': transform});
dbStream.on("end", function(){
res.write("{}]");
});
dbStream
.pipe(res);
вы пробовали пропусканием постное вариант в первом запросе? Node.find ({'dataset': datasetRef}). Lean(). Exec (function (err, nodes) {...}); – joao
Да. Дело в том, что документы ранее хранились как один массив в документе и сохранялись в gridfs. Таким образом, раньше, когда запрос был запрошен, ответ начал поток в течение нескольких миллисекунд. Теперь, если я перехожу от этой модели к этой нормированной модели, исключая gridfs, мне нужно использовать поток, иначе ответ откладывается с обратной стороны. –
можно каким-то образом использовать сквозной поток для замены шаблонов типа '} {' with '}, {'? Я пытаюсь, но не в состоянии это сделать –