@@ -38,7 +38,7 @@ import {
3838 UnprocessableEntityException ,
3939} from '@nestjs/common'
4040import { InjectModel } from '@nestjs/mongoose'
41- import { type FilterQuery , Model } from 'mongoose'
41+ import { type FilterQuery , Model , Types } from 'mongoose'
4242
4343import { CountersService } from '../counters/counters.service.js'
4444import { FilesService } from '../files/files.service.js'
@@ -142,18 +142,18 @@ export class ChangesService {
142142 this . logger . debug (
143143 '*** INSERT DATA EXCEPTION - Start to clean up old temporary documents...' ,
144144 )
145- await this . assemblyModel . deleteMany ( {
146- $and : [ { status : - 1 , user : uniqUserId } ] ,
147- } )
148- await this . featureModel . deleteMany ( {
149- $and : [ { status : - 1 , user : uniqUserId } ] ,
150- } )
151- await this . refSeqModel . deleteMany ( {
152- $and : [ { status : - 1 , user : uniqUserId } ] ,
153- } )
154- await this . refSeqChunkModel . deleteMany ( {
155- $and : [ { status : - 1 , user : uniqUserId } ] ,
156- } )
145+ await this . assemblyModel
146+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
147+ . exec ( )
148+ await this . featureModel
149+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
150+ . exec ( )
151+ await this . refSeqModel
152+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
153+ . exec ( )
154+ await this . refSeqChunkModel
155+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
156+ . exec ( )
157157 throw new UnprocessableEntityException ( String ( error ) )
158158 }
159159
@@ -185,68 +185,58 @@ export class ChangesService {
185185
186186 await this . featureModel . db . transaction ( async ( ) => {
187187 try {
188- await this . featureModel . updateMany (
189- {
190- $and : [ { status : - 1 , user : uniqUserId , _id : addedFeature . _id } ] ,
191- } ,
192- { $set : { status : 0 } } ,
193- )
188+ await this . featureModel
189+ . updateMany (
190+ {
191+ $and : [
192+ { status : - 1 , user : uniqUserId , _id : addedFeature . _id } ,
193+ ] ,
194+ } ,
195+ { $set : { status : 0 } } ,
196+ )
197+ . exec ( )
194198 } catch ( error ) {
195199 const err = error as Error
196200 this . logger . error (
197201 `Error setting status of add feature change to 0: ${ err . message } ` ,
198202 )
199- await this . featureModel . deleteMany ( {
200- $and : [ { status : - 1 , user : uniqUserId , _id : addedFeature . _id } ] ,
201- } )
203+ await this . featureModel
204+ . deleteMany ( {
205+ $and : [ { status : - 1 , user : uniqUserId , _id : addedFeature . _id } ] ,
206+ } )
207+ . exec ( )
202208 }
203209 } )
204210 }
205211 }
206212
207213 if ( STATUS_ZERO_CHANGE_TYPES . has ( change . typeName ) ) {
208- this . logger . debug ?.( '*** TEMPORARY DATA INSERTTED ***' )
214+ // manual finalization of change since the data is too big for a transaction
215+ this . logger . debug ( '*** TEMPORARY DATA INSERTED ***' )
209216 // Set "temporary document" -status --> "valid" -status i.e. (-1 --> 0)
210217 await this . featureModel . db . transaction ( async ( ) => {
211- this . logger . debug (
212- 'Updates "temporary document" -status --> "valid" -status' ,
213- )
214218 try {
215- // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
216- await this . assemblyModel . updateMany (
217- { $and : [ { status : - 1 , user : uniqUserId } ] } ,
218- { $set : { status : 0 } } ,
219- )
220- await this . refSeqChunkModel . updateMany (
221- { $and : [ { status : - 1 , user : uniqUserId } ] } ,
222- { $set : { status : 0 } } ,
223- )
224- await this . featureModel . updateMany (
225- { $and : [ { status : - 1 , user : uniqUserId } ] } ,
226- { $set : { status : 0 } } ,
227- )
228- await this . refSeqModel . updateMany (
229- { $and : [ { status : - 1 , user : uniqUserId } ] } ,
230- { $set : { status : 0 } } ,
231- )
219+ await this . batchUpdateMany ( this . assemblyModel , uniqUserId )
220+ await this . batchUpdateMany ( this . refSeqChunkModel , uniqUserId )
221+ await this . batchUpdateMany ( this . featureModel , uniqUserId )
222+ await this . batchUpdateMany ( this . refSeqModel , uniqUserId )
232223 } catch ( error ) {
233224 // Clean up old "temporary document" -documents
234225 this . logger . debug (
235226 '*** UPDATE STATUS EXCEPTION - Start to clean up old temporary documents...' ,
236227 )
237- // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
238- await this . assemblyModel . deleteMany ( {
239- $and : [ { status : - 1 , user : uniqUserId } ] ,
240- } )
241- await this . featureModel . deleteMany ( {
242- $and : [ { status : - 1 , user : uniqUserId } ] ,
243- } )
244- await this . refSeqModel . deleteMany ( {
245- $and : [ { status : - 1 , user : uniqUserId } ] ,
246- } )
247- await this . refSeqChunkModel . deleteMany ( {
248- $and : [ { status : - 1 , user : uniqUserId } ] ,
249- } )
228+ await this . assemblyModel
229+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
230+ . exec ( )
231+ await this . featureModel
232+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
233+ . exec ( )
234+ await this . refSeqModel
235+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
236+ . exec ( )
237+ await this . refSeqChunkModel
238+ . deleteMany ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
239+ . exec ( )
250240 throw new UnprocessableEntityException ( String ( error ) )
251241 }
252242 } )
@@ -333,4 +323,33 @@ export class ChangesService {
333323
334324 return change
335325 }
326+
327+ async batchUpdateMany (
328+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
329+ model : Model < any > ,
330+ uniqUserId : string ,
331+ ) {
332+ let docsToUpdate = await model
333+ . find ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
334+ . limit ( 1000 )
335+ . exec ( )
336+ let updatedCount = 0
337+ while ( docsToUpdate . length > 0 ) {
338+ const lengthBefore = updatedCount
339+ updatedCount += docsToUpdate . length
340+ this . logger . debug (
341+ `Finalizing ${ model . collection . name } ${ lengthBefore } to ${ updatedCount } ` ,
342+ )
343+ const idsToUpdate = docsToUpdate . map (
344+ ( doc ) => ( doc as { _id : Types . ObjectId } ) . _id ,
345+ )
346+ await model
347+ . updateMany ( { _id : idsToUpdate } , { $set : { status : 0 } } )
348+ . exec ( )
349+ docsToUpdate = await model
350+ . find ( { $and : [ { status : - 1 , user : uniqUserId } ] } )
351+ . limit ( 1000 )
352+ . exec ( )
353+ }
354+ }
336355}
0 commit comments