@@ -197,8 +197,9 @@ function MongoDB(settings, dataSource) {
197197 this . settings . enableOptimizedfindOrCreate === true ||
198198 this . settings . enableOptimizedFindOrCreate === true
199199 ) {
200- MongoDB . prototype . findOrCreate = optimizedFindOrCreate ;
200+ debug ( 'Optimized findOrCreate is enabled by default, and the enableOptimizedFindOrCreate setting is ignored since v7.0.0.' )
201201 }
202+
202203 if ( this . settings . enableGeoIndexing === true ) {
203204 MongoDB . prototype . buildNearFilter = buildNearFilter ;
204205 } else {
@@ -1509,6 +1510,94 @@ MongoDB.prototype.all = function all(modelName, filter, options, callback) {
15091510 }
15101511} ;
15111512
1513+ /**
1514+ * Find a matching model instances by the filter or create a new instance
1515+ *
1516+ * Only supported on mongodb 2.6+
1517+ *
1518+ * @param {String } modelName The model name
1519+ * @param {Object } data The model instance data
1520+ * @param {Object } filter The filter
1521+ * @param {Function } [callback] The callback function
1522+ */
1523+ MongoDB . prototype . findOrCreate = function findOrCreate ( modelName , filter , data , options , callback ) {
1524+ const self = this ;
1525+ if ( self . debug ) {
1526+ debug ( 'findOrCreate' , modelName , filter , data ) ;
1527+ }
1528+
1529+ if ( ! callback ) callback = options ;
1530+
1531+ const idValue = self . getIdValue ( modelName , data ) ;
1532+ const idName = self . idName ( modelName ) ;
1533+
1534+ if ( idValue == null ) {
1535+ delete data [ idName ] ; // Allow MongoDB to generate the id
1536+ } else {
1537+ const oid = self . coerceId ( modelName , idValue , options ) ; // Is it an Object ID?
1538+ data . _id = oid ; // Set it to _id
1539+ if ( idName !== '_id' ) {
1540+ delete data [ idName ] ;
1541+ }
1542+ }
1543+
1544+ filter = filter || { } ;
1545+ let query = { } ;
1546+ if ( filter . where ) {
1547+ if ( filter . where [ idName ] ) {
1548+ let id = filter . where [ idName ] ;
1549+ delete filter . where [ idName ] ;
1550+ id = self . coerceId ( modelName , id , options ) ;
1551+ filter . where . _id = id ;
1552+ }
1553+ query = self . buildWhere ( modelName , filter . where , options ) ;
1554+ }
1555+
1556+ const sort = self . buildSort ( modelName , filter . order , options ) ;
1557+
1558+ const projection = fieldsArrayToObj ( filter . fields ) ;
1559+
1560+ this . collection ( modelName ) . findOneAndUpdate (
1561+ query ,
1562+ { $setOnInsert : data } ,
1563+ { projection : projection , sort : sort , upsert : true } ,
1564+ function ( err , result ) {
1565+ if ( self . debug ) {
1566+ debug ( 'findOrCreate.callback' , modelName , filter , err , result ) ;
1567+ }
1568+ if ( err ) {
1569+ return callback ( err ) ;
1570+ }
1571+
1572+ let value = result . value ;
1573+ const created = ! ! result . lastErrorObject . upserted ;
1574+
1575+ if ( created && ( value == null || Object . keys ( value ) . length === 0 ) ) {
1576+ value = data ;
1577+ self . setIdValue ( modelName , value , result . lastErrorObject . upserted ) ;
1578+ } else {
1579+ value = self . fromDatabase ( modelName , value ) ;
1580+ self . setIdValue ( modelName , value , value . _id ) ;
1581+ }
1582+
1583+ if ( value && idName !== '_id' ) {
1584+ delete value . _id ;
1585+ }
1586+
1587+ if ( filter && filter . include ) {
1588+ self . _models [ modelName ] . model . include ( [ value ] , filter . include , function (
1589+ err ,
1590+ data ,
1591+ ) {
1592+ callback ( err , data [ 0 ] , created ) ;
1593+ } ) ;
1594+ } else {
1595+ callback ( null , value , created ) ;
1596+ }
1597+ } ,
1598+ ) ;
1599+ }
1600+
15121601/**
15131602 * Transform db data to model entity
15141603 *
@@ -2265,94 +2354,6 @@ function sanitizeFilter(filter, options) {
22652354
22662355exports . sanitizeFilter = sanitizeFilter ;
22672356
2268- /**
2269- * Find a matching model instances by the filter or create a new instance
2270- *
2271- * Only supported on mongodb 2.6+
2272- *
2273- * @param {String } modelName The model name
2274- * @param {Object } data The model instance data
2275- * @param {Object } filter The filter
2276- * @param {Function } [callback] The callback function
2277- */
2278- function optimizedFindOrCreate ( modelName , filter , data , options , callback ) {
2279- const self = this ;
2280- if ( self . debug ) {
2281- debug ( 'findOrCreate' , modelName , filter , data ) ;
2282- }
2283-
2284- if ( ! callback ) callback = options ;
2285-
2286- const idValue = self . getIdValue ( modelName , data ) ;
2287- const idName = self . idName ( modelName ) ;
2288-
2289- if ( idValue == null ) {
2290- delete data [ idName ] ; // Allow MongoDB to generate the id
2291- } else {
2292- const oid = self . coerceId ( modelName , idValue , options ) ; // Is it an Object ID?
2293- data . _id = oid ; // Set it to _id
2294- if ( idName !== '_id' ) {
2295- delete data [ idName ] ;
2296- }
2297- }
2298-
2299- filter = filter || { } ;
2300- let query = { } ;
2301- if ( filter . where ) {
2302- if ( filter . where [ idName ] ) {
2303- let id = filter . where [ idName ] ;
2304- delete filter . where [ idName ] ;
2305- id = self . coerceId ( modelName , id , options ) ;
2306- filter . where . _id = id ;
2307- }
2308- query = self . buildWhere ( modelName , filter . where , options ) ;
2309- }
2310-
2311- const sort = self . buildSort ( modelName , filter . order , options ) ;
2312-
2313- const projection = fieldsArrayToObj ( filter . fields ) ;
2314-
2315- this . collection ( modelName ) . findOneAndUpdate (
2316- query ,
2317- { $setOnInsert : data } ,
2318- { projection : projection , sort : sort , upsert : true } ,
2319- function ( err , result ) {
2320- if ( self . debug ) {
2321- debug ( 'findOrCreate.callback' , modelName , filter , err , result ) ;
2322- }
2323- if ( err ) {
2324- return callback ( err ) ;
2325- }
2326-
2327- let value = result . value ;
2328- const created = ! ! result . lastErrorObject . upserted ;
2329-
2330- if ( created && ( value == null || Object . keys ( value ) . length === 0 ) ) {
2331- value = data ;
2332- self . setIdValue ( modelName , value , result . lastErrorObject . upserted ) ;
2333- } else {
2334- value = self . fromDatabase ( modelName , value ) ;
2335- self . setIdValue ( modelName , value , value . _id ) ;
2336- }
2337-
2338- if ( value && idName !== '_id' ) {
2339- delete value . _id ;
2340- }
2341-
2342- if ( filter && filter . include ) {
2343- self . _models [ modelName ] . model . include ( [ value ] , filter . include , function (
2344- err ,
2345- data ,
2346- ) {
2347- callback ( err , data [ 0 ] , created ) ;
2348- } ) ;
2349- } else {
2350- callback ( null , value , created ) ;
2351- }
2352- } ,
2353- ) ;
2354- }
2355-
23562357/**
23572358 * @param {* } data Plain Data Object for the matching property definition(s)
23582359 * @param {* } modelCtor Model constructor
0 commit comments