Sharding
使用 GridFSBucket API 將流上傳到 gridfs 文件時,如何指定我自己的 id 值?
我正在使用 TypeScript、MongoDb 3.6 和 mongodb 3.0 驅動程序。這是我的做法:
this.gfs = new GridFSBucket(this.media_db, {bucketName: 'original'}); const reader = fs.createReadStream(path); const writer = this.gfs.openUploadStream(result.sha1); reader.pipe(writer); console.log("STORE ORIGINAL MongoDb/GridFs") const waiter = new Promise((resolve, reject) => { reader.on('end', ()=>resolve(true)); reader.on('error', reject); }); await waiter;
這個設置有一個大問題。這是我以前關於在 gridfs 集合上創建索引的問題:
我得到了一個答案,解釋了這些應該如何被索引:文件 id 應該有一個統一的分佈(例如一個散列鍵)。預設的 id 值不是這樣的,所以如果我希望它們從一開始就分佈在多個節點上,我必須提供我自己的文件 id。塊 id 是一個不同的故事——它們是生成的 objectid 值,它們應該保持平靜。為塊使用生成的 objectid 值允許 MongoDb 對塊執行範圍查詢,從而產生更有效的查詢計劃(例如,當需要為文件重建數據流時)。
問題是這樣的:使用官方 API 和 GridFSBucket 類,我如何指定自己的文件 id?這是應該如何完成的,但我看不到任何方法。這是該方法的簽名:
openUploadStream(filename: string, options?: GridFSBucketOpenUploadStreamOptions): GridFSBucketWriteStream;
它只有一個文件名參數和一個選項參數。選項是這樣的:
export interface GridFSBucketOpenUploadStreamOptions { chunkSizeBytes?: number, metadata?: Object, contentType?: string, aliases?: Array<string> }
如果無法做到這一點,那麼在向 gridfs 大量 ulpoading 文件時就無法避免熱分片。(那麼我可能需要送出一個問題。)
解決方案是 openUploadStreamWithId 方法。它有這個簽名:
openUploadStreamWithId(id: GridFSBucketWriteStreamId, filename: string, options?: GridFSBucketOpenUploadStreamOptions): GridFSBucketWriteStream;
GridFSBucketWriteStreamId 類型是這樣的:
type GridFSBucketWriteStreamId = string | number | Object | ObjectID;
所以你可以這樣稱呼它:
openUploadStreamWithId(your_custom_file_id, your_file_name)
如果自定義文件 id 是均勻分佈的並且塊在 (files_id, chunk_id) 上分片,那麼這將防止熱分片,並允許同時對塊進行範圍查詢。