diff --git a/lib/types/documentArray/methods/index.js b/lib/types/documentArray/methods/index.js index dae1baf105..04bee09916 100644 --- a/lib/types/documentArray/methods/index.js +++ b/lib/types/documentArray/methods/index.js @@ -2,7 +2,6 @@ const ArrayMethods = require('../../array/methods'); const Document = require('../../../document'); -const castObjectId = require('../../../cast/objectid'); const getDiscriminatorByValue = require('../../../helpers/discriminator/getDiscriminatorByValue'); const internalToObjectOptions = require('../../../options').internalToObjectOptions; const utils = require('../../../utils'); @@ -121,23 +120,39 @@ const methods = { * * @return {EmbeddedDocument|null} the subdocument or null if not found. * @param {ObjectId|String|Number|Buffer} id - * @TODO cast to the _id based on schema for proper comparison * @method id * @api public * @memberOf MongooseDocumentArray */ id(id) { - let casted; - let sid; - let _id; + if (id == null) { + return null; + } + + const schemaType = this[arraySchemaSymbol]; + let idSchemaType = null; + + if (schemaType && schemaType.schema) { + idSchemaType = schemaType.schema.path('_id'); + } else if (schemaType && schemaType.casterConstructor && schemaType.casterConstructor.schema) { + idSchemaType = schemaType.casterConstructor.schema.path('_id'); + } else if (this.length > 0 && this[0] != null && this[0].$__schema) { + idSchemaType = this[0].$__schema.path('_id'); + } - try { - casted = castObjectId(id).toString(); - } catch (e) { - casted = null; + let castedId = id; + if (idSchemaType) { + try { + castedId = idSchemaType.cast(id); + } catch (e) { + castedId = null; + } } + let sid; + let _id; + for (const val of this) { if (!val) { continue; @@ -152,11 +167,17 @@ const methods = { if (sid == _id._id) { return val; } - } else if (!isBsonType(id, 'ObjectId') && !isBsonType(_id, 'ObjectId')) { - if (id == _id || utils.deepEqual(id, _id)) { + } else if (castedId != null && !isBsonType(castedId, 'ObjectId') && !isBsonType(_id, 'ObjectId')) { + if (castedId == _id || utils.deepEqual(castedId, _id)) { return val; } - } else if (casted == _id) { + } else if (castedId != null && isBsonType(castedId, 'ObjectId') && isBsonType(_id, 'ObjectId')) { + if (castedId.toString() === _id.toString()) { + return val; + } + } else if (castedId != null && castedId == _id) { + return val; + } else if (castedId == null && (id == _id || utils.deepEqual(id, _id))) { return val; } }