簡體   English   中英

從 MongoDB 檢索圖像的最佳方法是什么?

[英]what is the best approach to retrieve images from MongoDB?

我有一個 web 應用程序,它使用 GridFS 從 MongoDB 存儲和檢索圖像。 我的問題是,當用戶發出提示服務器從數據庫中檢索圖像的請求時,需要很長時間。

例如,僅檢索數據庫中的兩個文檔然后遍歷每個文檔以獲取與每個文檔關聯的圖像的請求最多可能需要 45 秒。 在這種情況下,從數據庫中檢索到的圖像總量約為 10 張。

這是我的方法:

// 1. Query the database 
var users = await User.find({ 'key’': value });

// 5. Use GridFs to get the image and return the result 
const createStream = (filename) => {

        return new Promise((resolve, reject) => {
            let readstream = gfs.createReadStream(filename);
            let fileChunks = [];

            readstream.on('data', function (chunk) {
                fileChunks.push(chunk);
            });

            readstream.on('end', function () {
                let concatFile = Buffer.concat(fileChunks);
                let imageFormated = Buffer(concatFile).toString("base64");
                resolve(imageFormated)
            });
       })
}




// 4. Iterate though each of the images info and retrieve the file name so it can be used with gfs.createReadStream( );
 const iterateImages = async (currentPlaceImages) => {

        let imagesFormattedArray = [];

        for (var i = 0; i < currentPlaceImages.length; i++) {

            let filename = currentPlaceImages[i].filename;

            // console.log(filename);

            let imageFormated = await createStream(filename);
            // console.log(imageFormated);
            imagesFormattedArray.push(imageFormated)
            if (i === currentPlaceImages.length - 1) {
                return imagesFormattedArray
            }

        }

 }


// 3. favPlaces represents  a field-value pair of each document that  contains an object of ‘favorite places’, each of which with a ‘placeImage’ array of all the images associated with a place

const getImagesOfPlace = async (favPlaces) => {

        let imagesStreamArray = [];

        for (var w = 0; w < favPlaces.length; w++) {.

            let currentPlaceImages = favPlaces[w]['placeImage'];
            let imagesStream = await iterateImages(currentPlaceImages);
            imagesStreamArray.push(imagesStream);

            if (w === favPlaces.length - 1) {

                return imagesStreamArray;
            }

        };
   }

// 2. Loop through the documents  retrieved from the database and access the field - value pair that contains the information of the images that I want to retrieve using GridFs 
let arrayOfUsers = [];

const getImages = async () => {

        let arrayOfFormattedImages = [];

        for (var i = 0; i < users.length; i++) {

                    let favPlaces = users[i]['favoritePlaces'];
                    let stream = await getImagesOfPlace(favPlaces);

                   userObj['imageFormatted'] = stream;
                   arrayOfUsers.push(userObj);
        }
};

await getImages();

這是流程的可視化表示在此處輸入圖像描述

如前所述,這種方法需要很長時間才能獲得服務器響應。 如果有人知道更好、更有效、更快速的方法,請告訴我。

謝謝!

因為您使用for循環,圖像將一個接一個地加載而不是一次全部加載,循環將迭代然后等待然后再次迭代並等待等等......您需要立即觸發所有異步操作並等待所有其中完成, Promise.all使用Array.map是一種方法。 嘗試這樣的事情:

const iterateImages = (currentPlaceImages) => {
  return Promise.all(
    currentPlaceImages.map(async (i) => {
      const filename = i.filename;
      return createStream(filename);
    })
  );
};

const getImagesOfPlace = async (favPlaces) => {
  return Promise.all(
    favPlaces.map(async (p) => {
      const currentPlaceImages = p.placeImage;
      return iterateImages(currentPlaceImages);
    })
  );
};

const getImages = async () => {
  return Promise.all(
    users.map(async (u) => {
      const favPlaces = u.favoritePlaces;
      const stream = await getImagesOfPlace(favPlaces);
      u.imageFormatted = stream;
      return u
    })
  );
};

let arrayOfUsers = await getImages();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM