Reputation: 4650
I am writing a Node.JS application using MongoDB and Mongoose. One of the issues I've faced is that I need to find the element either by its ObjectID
or by url
field. I tried to write it this way:
const mongoose = require('mongoose');
const ObjectID = mongoose.Types.ObjectId;
Event
.findOne({ $or: [
{ _id: new ObjectID('hello) },
{ url: 'hello },
] })
// doing domething with the result
However if the string is not a valid ObjectID
, the program will crash, saying it is not a valid ObjectID
string:
Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters
at new ObjectID (/usr/app/oms-events/node_modules/bson/lib/bson/objectid.js:34:11)
at Server.exports.fetchSingleEvent (/usr/app/oms-events/lib/middlewares.js:178:14)
at next (/usr/app/oms-events/node_modules/restify/lib/server.js:912:30)
at f (/usr/app/oms-events/node_modules/once/once.js:25:25)
at Request.httprequest [as _callback] (/usr/app/oms-events/lib/middlewares.js:165:14)
at Request.self.callback (/usr/app/oms-events/node_modules/request/request.js:186:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/usr/app/oms-events/node_modules/request/request.js:1081:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/usr/app/oms-events/node_modules/request/request.js:1001:12)
at IncomingMessage.g (events.js:292:16)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
Program node /usr/app/oms-events/lib/server.js exited with code 1
If I will remove the conversion to ObjectID, like here:
Event
.findOne({ $or: [
{ _id: 'hello' },
{ url: 'hello' },
] })
it will also crash with CastError
:
{ MongooseError: Cast to ObjectId failed for value "hello" at path "_id"
at CastError (/usr/app/oms-events/node_modules/mongoose/lib/error/cast.js:26:11)
at ObjectId.cast (/usr/app/oms-events/node_modules/mongoose/lib/schema/objectid.js:147:13)
at ObjectId.castForQuery (/usr/app/oms-events/node_modules/mongoose/lib/schema/objectid.js:187:15)
at cast (/usr/app/oms-events/node_modules/mongoose/lib/cast.js:218:32)
at cast (/usr/app/oms-events/node_modules/mongoose/lib/cast.js:36:18)
at model.Query.Query.cast (/usr/app/oms-events/node_modules/mongoose/lib/query.js:2741:10)
at model.Query.Query.findOne (/usr/app/oms-events/node_modules/mongoose/lib/query.js:1354:10)
at /usr/app/oms-events/node_modules/mongoose/lib/query.js:2300:21
at model.Query.exec (/usr/app/oms-events/node_modules/mongoose/lib/query.js:2294:17)
at Server.exports.fetchSingleEvent (/usr/app/oms-events/lib/middlewares.js:182:6)
at next (/usr/app/oms-events/node_modules/restify/lib/server.js:912:30)
at f (/usr/app/oms-events/node_modules/once/once.js:25:25)
at Server.exports.fetchUserDetails (/usr/app/oms-events/lib/middlewares.js:92:12)
at next (/usr/app/oms-events/node_modules/restify/lib/server.js:912:30)
at f (/usr/app/oms-events/node_modules/once/once.js:25:25)
at UserCache.findOne (/usr/app/oms-events/lib/middlewares.js:85:12)
message: 'Cast to ObjectId failed for value "hello" at path "_id"',
name: 'CastError',
kind: 'ObjectId',
value: 'hello',
path: '_id',
reason: undefined }
So, the question is: how can I find an element by either ObjectID
or url
field?
Upvotes: 0
Views: 1362
Reputation: 4650
I decided to do it this way:
let id = 'hello'
// Checking if the passed ID is ObjectID or not.
// I decided not to use ObjectID.isValid method, since it's not always
// working properly, see http://stackoverflow.com/a/29231016/1206421
let findObject;
if (id.match(/^[0-9a-fA-F]{24}$/)) { // if it's indeed an ObjectID
findObject = { _id: id };
} else {
findObject = { url: id };
}
return Event
.findOne(findObject)
// doing something with the result
Upvotes: 1