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
380 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!

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