Mongoose find() RegExp for Number type field

I'm try to create a table with filters and when i need find rows through regular expression i have error below. How i can use RegExp with field type of Number? Change field type on String, is a good idea?

var ContractSchema = new Schema({
  userId: {type: Schema.Types.ObjectId, ref: 'User'},
  number: Number,
  // ...
});

module.exports = mongoose.model('Contract', ContractSchema);

Contract.find({number: /555/}, function(err, contracts){
  console.log(err, contracts);
});

Cast to number failed for value "/555/" at path "number"

Upvotes: 4

Views: 13092

Answers (3)

Max Starling
Max Starling

Reputation: 1037

If you can't use $where (i.e. if you use mongoose-paginate-v2) then replace $where with $expr:

const fieldName = 'number'
const regExp = new RegExp(555);

const query = {
  $expr: {
    $regexMatch: {
      input: { $toString: `$${fieldName}` },
      regex: regExp,
    },
};

Contract.find(query);

Upvotes: 2

Martin Konecny
Martin Konecny

Reputation: 59671

Either convert your number to type string for each document, and then you can use Regular Expressions properly and efficiently, or just give up on using RegEx's, and use the built in Mongo filtering options instead.

For example, to find a number with a particular value:

{number: 555}

Or to find a number in the range (500, 600):

{number: {$gt: 500, $lt: 600}}

Here is a list of some common query operators.

Either of these is more efficient than converting each Number to a String at query time.

Upvotes: -1

user3561036
user3561036

Reputation:

Well regular expressions only work on strings of course. You could however still do this, though it's highly inefficient to do so:

Contract.find(
    { "$where": "function() { return this.number.toString().match(/555/) != null; }" }
).function(err,contracts) {
   // do something with results
});

The MongoDB $where query operator allows for a JavaScript condition to be evaluated on the server for each document in the collection or those left from other query conditions.

Basically that evaluation converts the field value to a String and then allows a regex operation on it.

Otherwise, you change your content or add another field for a string representation. But unless you are using an anchor ^ from the start of the string, then even a $regex operation on an actual string field is barely more efficient than using the JavaScript evaluation as shown.

P.S Make sure your server allows JavaScript evaluation. Some people choose to turn this off. But it should be on by default.

Upvotes: 5

Related Questions