@@ -628,11 +628,30 @@ class CoreMongooseArray extends Array {
628628
629629 _checkManualPopulation ( this , arguments ) ;
630630
631+ const parent = this [ arrayParentSymbol ] ;
631632 let values = [ ] . map . call ( arguments , this . _mapCast , this ) ;
632- values = this [ arraySchemaSymbol ] . applySetters ( values , this [ arrayParentSymbol ] , undefined ,
633+ values = this [ arraySchemaSymbol ] . applySetters ( values , parent , undefined ,
633634 undefined , { skipDocumentArrayCast : true } ) ;
634635 const ret = [ ] . push . apply ( this , values ) ;
635636
637+ // If this is a document array, each element may contain single
638+ // populated paths, so we need to modify the top-level document's
639+ // populated cache. See gh-8247.
640+ if ( this . isMongooseDocumentArray && parent . $__ . populated != null ) {
641+ const populatedPaths = Object . keys ( parent . $__ . populated ) .
642+ filter ( p => p . startsWith ( this [ arrayPathSymbol ] + '.' ) ) ;
643+
644+ for ( const path of populatedPaths ) {
645+ const remnant = path . slice ( ( this [ arrayPathSymbol ] + '.' ) . length ) ;
646+ if ( ! Array . isArray ( parent . $__ . populated [ path ] . value ) ) {
647+ continue ;
648+ }
649+ for ( const val of values ) {
650+ parent . $__ . populated [ path ] . value . push ( val . populated ( remnant ) ) ;
651+ }
652+ }
653+ }
654+
636655 this . _registerAtomic ( '$push' , values ) ;
637656 this . _markModified ( ) ;
638657 return ret ;
0 commit comments