J'ai besoin de lire un gros fichier JSON (environ 630 Mo) dans Nodejs et d'insérer chaque objet dans MongoDB.
J'ai lu la réponse ici: Analyser un gros fichier JSON dans Nodejs .
Cependant, les réponses gèrent le fichier JSON ligne par ligne, au lieu de le gérer objet par objet. Ainsi, je ne sais toujours pas comment obtenir un objet de ce fichier et le faire fonctionner.
J'ai environ 100 000 objets de ce type dans mon fichier JSON.
Format des données:
[
{
"id": "0000000",
"name": "Donna Blak",
"livingSuburb": "Tingalpa",
"age": 53,
"nearestHospital": "Royal Children's Hospital",
"treatments": {
"19890803": {
"medicine": "Stomach flu B",
"disease": "Stomach flu"
},
"19740112": {
"medicine": "Progeria C",
"disease": "Progeria"
},
"19830206": {
"medicine": "Poliomyelitis B",
"disease": "Poliomyelitis"
}
},
"class": "patient"
},
...
]
À votre santé,
Alex
Il y a un module Nice nommé 'stream-json' qui fait exactement ce que vous voulez.
Il peut analyser les fichiers JSON dépassant de loin la mémoire disponible.
et
StreamArray gère un cas d'utilisation fréquent: un vaste éventail d'objets relativement petits similaires aux vidages de base de données produits par Django. Il diffuse les composants de la baie individuellement en prenant soin de les assembler automatiquement.
Voici un exemple très basique:
const StreamArray = require('stream-json/streamers/StreamArray');
const path = require('path');
const fs = require('fs');
const jsonStream = StreamArray.withParser();
//You'll get json objects here
//Key is an array-index here
jsonStream.on('data', ({key, value}) => {
console.log(key, value);
});
jsonStream.on('end', () => {
console.log('All done');
});
const filename = path.join(__dirname, 'sample.json');
fs.createReadStream(filename).pipe(jsonStream.input);
Si vous souhaitez faire quelque chose de plus complexe, par exemple traiter un objet après un autre séquentiellement (en gardant l'ordre) et appliquer des opérations asynchrones pour chacun d'eux, vous pouvez faire le flux d'écriture personnalisé comme ceci:
const StreamArray = require('stream-json/streamers/StreamArray');
const {Writable} = require('stream');
const path = require('path');
const fs = require('fs');
const fileStream = fs.createReadStream(path.join(__dirname, 'sample.json'));
const jsonStream = StreamArray.withParser();
const processingStream = new Writable({
write({key, value}, encoding, callback) {
//Save to mongo or do any other async actions
setTimeout(() => {
console.log(value);
//Next record will be read only current one is fully processed
callback();
}, 1000);
},
//Don't skip this, as we need to operate with objects, not buffers
objectMode: true
});
//Pipe the streams as follows
fileStream.pipe(jsonStream.input);
jsonStream.pipe(processingStream);
//So we're waiting for the 'finish' event when everything is done.
processingStream.on('finish', () => console.log('All done'));
Veuillez noter: Les exemples ci-dessus sont testés pour '[email protected]'. Pour certaines versions précédentes (vraisemblablement antérieures à 1.0.0), vous devrez peut-être:
const StreamArray = require('stream-json/utils/StreamArray');
et alors
const jsonStream = StreamArray.make();