Rumah > hujung hadapan web > tutorial js > Dari Storan ke Strim: Menghantar Data MongoDB Terus kepada Pengguna

Dari Storan ke Strim: Menghantar Data MongoDB Terus kepada Pengguna

DDD
Lepaskan: 2025-01-04 04:34:38
asal
324 orang telah melayarinya

From Storage to Stream: Delivering MongoDB Data Directly to Users

Langkah 1: Kursor MongoDB

Begini cara kami menyediakan kursor (menggunakan semula coretan anda):

const cursor =
    userObject?.data?.serviceProviderName === 'ZYRO'
        ? zyroTransactionModel.find(query).cursor()
        : finoTransactionModel.find(query).cursor();

console.log("Cursor created successfully");
Salin selepas log masuk

Langkah 2: Sediakan Fail ZIP
Gunakan pustaka yazl untuk menstrim data CSV ke dalam fail ZIP:

const yazl = require('yazl');
const zipfile = new yazl.ZipFile();

reply.raw.writeHead(200, {
    "Content-Type": "application/zip",
    "Content-Disposition": "attachment; filename=transactions.zip",
});

zipfile.outputStream.pipe(reply.raw);

const cleanup = async () => {
    console.log("Cleaning up resources...");
    zipfile.end(); // Finalize ZIP
    await cursor.close();
};
reply.raw.on("close", cleanup);
reply.raw.on("error", cleanup);
Salin selepas log masuk

Langkah 3: Mencipta Strim CSV Dinamik
Jana data CSV secara dinamik dan strimkannya ke dalam fail ZIP:

const createNewCSVStream = (headers) => {
    const csvStream = new Readable({ read() {} });
    csvStream.push(headers.join(",") + "\n"); // Add headers
    return csvStream;
};

const filteredHeaders = getHeaders(transactionDownloadFields, userObject?.state?.auth?.role);
const currentCSVStream = createNewCSVStream(filteredHeaders);

zipfile.addReadStream(currentCSVStream, "transactions_part_1.csv");
Salin selepas log masuk

Langkah 4: Menstrim Data MongoDB ke CSV
Strim data daripada MongoDB terus ke CSV:

cursor.on('data', (doc) => {
    const csvRow = filteredHeaders.map(header => doc[header.key] || '').join(',');
    currentCSVStream.push(csvRow + '\n'); // Write row
});

cursor.on('end', () => {
    currentCSVStream.push(null); // End the stream
    zipfile.end(); // Finalize the ZIP
});

Salin selepas log masuk

Langkah 5: Memproses Data daripada Kursor MongoDB
Strim dokumen daripada kursor MongoDB, ubahnya mengikut keperluan dan tulis baris secara dinamik ke strim CSV:

try {
    for await (const doc of cursor) {
        if (clientDisconnected) {
            console.log("Client disconnected. Stopping processing...");
            break;
        }

        streamedCount++;
        rowCount++;

        let row = "";
        const filteredHeaders = getHeaders(
            transactionDownloadFields,
            userObject?.state?.auth?.role
        );

        for (let i = 0; i < filteredHeaders.length; i++) {
            const field = filteredHeaders[i];

            // Fetch the corresponding field configuration from transactionDownloadFields
            const originalField = transactionDownloadFields.find((f) => f.value === field.value);

            // Get the value from the transaction document
            let value = getValueFromTransaction(doc, field.value);

            // Apply transformation if the field has a transform function
            if (originalField?.transform) {
                value = originalField.transform(value);
            }

            // Enclose the value in double quotes
            value = value !== undefined ? `"${value}"` : '"N/A"';
            row += (i > 0 ? "," : "") + value;
        }
        row += "\n";
        currentCSVStream.push(row);

        // Check if the row count has reached the threshold for the current CSV file
        if (rowCount >= MAX_ROWS_PER_FILE) {
            console.log(`Threshold reached for file ${fileIndex - 1}. Starting new file...`);
            currentCSVStream.push(null); // End the current CSV stream
            currentCSVStream = createNewCSVStream(); // Start a new stream
            rowCount = 0; // Reset the row count
        }
    }

    // Finalize the current CSV stream if it has data
    if (currentCSVStream) {
        currentCSVStream.push(null);
    }

    // Finalize the ZIP file
    zipfile.end();
    console.log(`Successfully streamed ${streamedCount} rows across ${fileIndex - 1} files.`);
} catch (error) {
    console.error("Error during processing:", error);
    if (!headersSent) reply.status(500).send({ error: "Failed to generate ZIP file" });
} finally {
    // Cleanup: Close the MongoDB cursor
    await cursor.close().catch((err) => console.error("Error closing cursor:", err));
}
Salin selepas log masuk

Ringkasan

Penggunaan Lelaran Dokumen untuk menunggu...daripada:

Strim dokumen satu demi satu daripada kursor MongoDB dengan cekap.
Mendayakan pemprosesan masa nyata tanpa memuatkan semua data ke dalam memori.

  • Penjanaan Baris CSV Dinamik:

Membina setiap baris secara dinamik dengan mengulangi pada Headers yang ditapis.
Menggunakan transformasi menggunakan fungsi transformasi, jika ditakrifkan dalam transactionDownloadFields.
Ambang Baris dan Pemisahan Fail:

Memantau kiraan baris terhadap ambang (MAX_ROWS_PER_FILE).
Menamatkan strim CSV semasa dan memulakan strim baharu apabila ambang dicapai.

  • Pengendalian Ralat:

Melog dan menghantar respons ralat jika isu berlaku semasa pemprosesan.
Memastikan pembersihan yang betul dengan menutup kursor MongoDB dalam blok akhirnya.

  • Memuktamadkan Strim:

Menolak null untuk menamatkan strim CSV semasa.
Melengkapkan fail ZIP setelah semua baris diproses.

Atas ialah kandungan terperinci Dari Storan ke Strim: Menghantar Data MongoDB Terus kepada Pengguna. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan