9

Is it possible to do a query like:

db.artigo.find( { _id : ObjectId('520a504a3004bc615fcfcf16') } )

but using a regex on ObjectId?

For example, do get _ids that contains "004" on that position above.

PS. The reason is to implement a shorty service based on some fields, namely the _id. I'm trying to create an implicit "shorty" service instead of an explicit one (with a field generated for the purpose).

Luís Soares
  • 5,726
  • 4
  • 39
  • 66
  • Mongo `_id` is objectId not string check this http://stackoverflow.com/questions/20988446/regex-for-mongodb-objectid – Neo-coder Apr 10 '15 at 19:28

4 Answers4

5
  • ObjectId is not a string but a special type in MongoDB. You can not
    query with a regex expression operator against a field that contains ObjectId's.
  • But... _id doesn't have to be an ObjectId, so what i would suggest is providing your own unique string as _id then you can use a regex
    expression for querying.
nickmilon
  • 1,332
  • 1
  • 10
  • 9
  • hmm.. I was avoiding an extra field and a script do create it... thanks :) – Luís Soares Apr 10 '15 at 19:53
  • you can avoid the extra field by assigning the a string to _id. mongoDB can produce this for you – nickmilon Apr 10 '15 at 20:10
  • not sure if I got it. how would the query look like? – Luís Soares Apr 10 '15 at 20:13
  • the query would look like something similar to what Brian suggestested db.artigo.find( { _id : { $regex: any_valid_js_regex_exp } } ) but it will work only if you have stored a string in _id field you can use x=new ObjectId() in mongo to produce an ObjectId then convert it to string x.toString() before saving the document in db. Have in mind though that regex queries are slow in mongoDB unless you lookup from beginning of string ('^xxxxx') – nickmilon Apr 10 '15 at 20:23
  • but I have millions of documents which were not saved that way. – Luís Soares Apr 10 '15 at 20:25
  • then I don't see a solution by using regex :-( – nickmilon Apr 10 '15 at 20:30
  • do you have any alternative to make the ObjectId shorter (compress it)? I mean... that's a 24 char base 16.... I want to use [a-zA-Z-09] to compress it – Luís Soares Apr 10 '15 at 20:32
5

ObjectId is not a string but a special type in MongoDB. You can not query with a regex expression operator against a field that contains ObjectId's.

_id doesn't have to be an ObjectId, so what I would suggest is providing your own unique string as _id then you can use a regex the expression for querying.

Example:

let userId = 'bf44fa';

const result = await Users.aggregate([
  {
    $addFields: {
      tempUserId: { $toString: '$_id' },
    }
  },
  {
    $match: {
      tempUserId: { $regex: userId, $options: "i" }
    }
  }
]).exec();

Now we can find by _id with the last 6 digits or start 6 digits by using aggregation as your wish.

Farrukh Malik
  • 746
  • 9
  • 13
1

I believe this is one of the areas where mongodb is lacking; and also the team @ mongodb looks like they won't support this feature as this (https://jira.mongodb.org/browse/SERVER-1146) jira issue indicates. The argument seems to be to use our own id that is of string format but objectIds make sense in big systems where you have large volumes of transactions e.g. Amazons order numbers

The Solution I cam up with is as follows:

I created another column that copies the first six digits of my _id field and is of string type . The reason I choose the first 6 digits of my _id field are; one to save space and be compact and also at the end of the day the reason I need a regex expression is for searching purpose and that fits well for my needs.

Derese Getachew
  • 440
  • 6
  • 10
-4

This is what you need:

db.artigo.find( { _id : { $regex: '004' } } )

Brian Stephens
  • 5,161
  • 19
  • 25
  • @LuísSoares: that syntax is correct, so I don't know why it's not matching for you. Here's the documentation: http://docs.mongodb.org/manual/reference/operator/query/regex/ – Brian Stephens Apr 10 '15 at 19:04
  • The problem is that _id is not a string. It's an ObjectId as shown in the screenshot :\ – Luís Soares Apr 10 '15 at 19:06
  • @LuísSoares: Ah, now I see your problem. There is a "str" attribute of the ObjectId that returns just the string hex. Could you perform the $regex match against that? – Brian Stephens Apr 10 '15 at 19:22
  • No you can't do that either ObjectId.toString() can convert and ObjectId to a string only after it is retrieved from db. – nickmilon Apr 10 '15 at 19:33
  • I'm not sure why someone flagged this… code-only, maybe? Just in case, if you update it, try adding a bit more substance outside the code block. – Nathan Tuggy Apr 11 '15 at 02:18