如何基于关键词在MongoDB Mongoose中查询ObjectId/_id?
LIKE for ID) Got it, let's tackle this problem! Since MongoDB's ObjectId isn't a plain string—it's a 12-byte BSON type—you can't directly run a LIKE-style query like you do in MySQL. But don't worry, there are a few straightforward ways to pull off this fuzzy match with Mongoose.
Method 1: Direct Regex Match on _id
Mongoose will implicitly convert ObjectId values to their hex string representations when using a regex on the _id field. This is the simplest approach for basic use cases:
const searchKeyword = "5f9"; // Your user's input keyword // Query documents where _id's hex string contains the keyword const matchingDocs = await YourMongooseModel.find({ _id: { $regex: searchKeyword, $options: "i" } // "i" enables case-insensitive matching (optional) });
This works because when MongoDB evaluates the regex against the _id field, it casts the ObjectId to its human-readable hex string first.
Method 2: Explicit String Conversion with Aggregation
If you need more control (or you're working within an aggregation pipeline), use the $toString operator to explicitly convert _id to a string, then match with $regexMatch:
const searchKeyword = "abc123"; const matchingDocs = await YourMongooseModel.aggregate([ { $match: { $expr: { $regexMatch: { input: { $toString: "$_id" }, regex: searchKeyword, options: "i" } } } } ]);
This is great for complex queries where you're already aggregating data, or if you want to avoid relying on implicit type conversion.
Method 3: Optimize for Performance (Add a String Field)
A heads-up: regex queries on converted ObjectId values won't use MongoDB's built-in _id index. If you're working with a large collection and need fast fuzzy searches, consider storing the _id hex string as a dedicated field in your documents.
Here's how to set that up in your schema:
const yourSchema = new mongoose.Schema({ // Your existing fields go here }, { timestamps: true }); // Option 1: Virtual field (not stored in DB, computed on the fly) yourSchema.virtual('idString').get(function() { return this._id.toString(); }); // Option 2: Persisted field (stored in DB, indexed for fast queries) yourSchema.pre('save', function(next) { this.idString = this._id.toString(); next(); }); // Create an index on the persisted idString field yourSchema.index({ idString: 1 });
Then query against this dedicated string field for better performance:
const matchingDocs = await YourMongooseModel.find({ idString: { $regex: searchKeyword, $options: "i" } });
This approach leverages the index on idString, making your fuzzy queries much faster for large datasets.
内容的提问来源于stack exchange,提问作者Jackwander

