I want to query something with SQL's like
query:
SELECT * FROM users WHERE name LIKE '%m%'
How can I achieve the same in MongoDB? I can't find an operator for like
in the documentation.
I want to query something with SQL's like
query:
SELECT * FROM users WHERE name LIKE '%m%'
How can I achieve the same in MongoDB? I can't find an operator for like
in the documentation.
That would have to be:
db.users.find({"name": /.*m.*/})
Or, similar:
db.users.find({"name": /m/})
You're looking for something that contains "m" somewhere (SQL's '%
' operator is equivalent to regular expressions' '.*
'), not something that has "m" anchored to the beginning of the string.
Note: MongoDB uses regular expressions which are more powerful than "LIKE" in SQL. With regular expressions you can create any pattern that you imagine.
For more information on regular expressions, refer to Regular expressions (MDN).
db.users.insert({name: 'paulo'})
db.users.insert({name: 'patric'})
db.users.insert({name: 'pedro'})
Therefore:
For:
db.users.find({name: /a/}) // Like '%a%'
Output: paulo, patric
For:
db.users.find({name: /^pa/}) // Like 'pa%'
Output: paulo, patric
For:
db.users.find({name: /ro$/}) //like '%ro'
Output: pedro
Here are different types of requirements and solutions for string search with regular expressions.
You can do with a regular expression which contains a word, i.e., like. Also you can use $options => i
for a case insensitive search.
string
db.collection.find({name:{'$regex' : 'string', '$options' : 'i'}})
string
, only with a regular expressiondb.collection.find({name:{'$regex' : '^((?!string).)*$', '$options' : 'i'}})
string
db.collection.find({name:{'$regex' : '^string$', '$options' : 'i'}})
string
db.collection.find({name:{'$regex' : '^string', '$options' : 'i'}})
string
db.collection.find({name:{'$regex' : 'string$', '$options' : 'i'}})
Keep Regular Expressions Cheat Sheet as a bookmark, and a reference for any other alterations you may need.
You have two choices:
db.users.find({"name": /string/})
or
db.users.find({"name": {"$regex": "string", "$options": "i"}})
For the second one, you have more options, like "i" in options to find using case insensitive.
And about the "string", you can use like ".string." (%string%), or "string.*" (string%) and ".*string) (%string) for example. You can use a regular expression as you want.
In a Node.js project and using Mongoose, use a like query:
var User = mongoose.model('User');
var searchQuery = {};
searchQuery.email = req.query.email;
searchQuery.name = {$regex: req.query.name, $options: 'i'};
User.find(searchQuery, function(error, user) {
if(error || user === null) {
return res.status(500).send(error);
}
return res.status(200).send(user);
});
You can use a where statement to build any JavaScript script:
db.myCollection.find( { $where: "this.name.toLowerCase().indexOf('m') >= 0" } );
Reference: $where
For PHP mongo Like.
I had several issues with PHP mongo like. I found that concatenating the regular expression parameters helps in some situations - PHP mongo find field starts with.
For example,
db()->users->insert(['name' => 'john']);
db()->users->insert(['name' => 'joe']);
db()->users->insert(['name' => 'jason']);
// starts with
$like_var = 'jo';
$prefix = '/^';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);
output: (joe, john)
// contains
$like_var = 'j';
$prefix = '/';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);
output: (joe, john, jason)
In SQL, the ‘like’ query looks like this:
select * from users where name like '%m%'
In the MongoDB console, it looks like this:
db.users.find({"name": /m/}) // Not JSON formatted
db.users.find({"name": /m/}).pretty() // JSON formatted
In addition, the pretty()
method will produce a formatted JSON structure in all the places which is more readable.
Regular expressions are expensive to process.
Another way is to create an index of text and then search it using $search
.
Create a text index of fields you want to make searchable:
db.collection.createIndex({name: 'text', otherField: 'text'});
Search for a string in the text index:
db.collection.find({
'$text'=>{'$search': "The string"}
})
Use regular expressions matching as below. The 'i' shows case insensitivity.
var collections = mongoDatabase.GetCollection("Abcd");
var queryA = Query.And(
Query.Matches("strName", new BsonRegularExpression("ABCD", "i")),
Query.Matches("strVal", new BsonRegularExpression("4121", "i")));
var queryB = Query.Or(
Query.Matches("strName", new BsonRegularExpression("ABCD","i")),
Query.Matches("strVal", new BsonRegularExpression("33156", "i")));
var getA = collections.Find(queryA);
var getB = collections.Find(queryB);
A like query would be as shown below:
db.movies.find({title: /.*Twelve Monkeys.*/}).sort({regularizedCorRelation : 1}).limit(10);
For the Scala ReactiveMongo API,
val query = BSONDocument("title" -> BSONRegex(".*" + name + ".*", "")) // like
val sortQ = BSONDocument("regularizedCorRelation" -> BSONInteger(1))
val cursor = collection.find(query).sort(sortQ).options(QueryOpts().batchSize(10)).cursor[BSONDocument]
It seems that there are reasons for using both the JavaScript /regex_pattern/
pattern as well as the MongoDB {'$regex': 'regex_pattern'}
pattern. See: MongoDB RegEx Syntax Restrictions
This is not a complete regular expression tutorial, but I was inspired to run these tests after seeing a highly voted ambiguous post above.
> ['abbbb','bbabb','bbbba'].forEach(function(v){db.test_collection.insert({val: v})})
> db.test_collection.find({val: /a/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }
> db.test_collection.find({val: /.*a.*/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }
> db.test_collection.find({val: /.+a.+/})
{ "val" : "bbabb" }
> db.test_collection.find({val: /^a/})
{ "val" : "abbbb" }
> db.test_collection.find({val: /a$/})
{ "val" : "bbbba" }
> db.test_collection.find({val: {'$regex': 'a$'}})
{ "val" : "bbbba" }
If you want a 'like' search in MongoDB then you should go with $regex. By using it, the query will be:
db.product.find({name:{$regex:/m/i}})
For more, you can read the documentation as well - $regex
You can query with a regular expression:
db.users.find({"name": /m/});
If the string is coming from the user, maybe you want to escape the string before using it. This will prevent literal chars from the user to be interpreted as regex tokens.
For example, searching the string "A." will also match "AB" if not escaped.
You can use a simple replace
to escape your string before using it. I made it a function for reusing:
function textLike(str) {
var escaped = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
return new RegExp(escaped, 'i');
}
So now, the string becomes a case-insensitive pattern matching also the literal dot. Example:
> textLike('A.');
< /A\./i
Now we are ready to generate the regular expression on the go:
db.users.find({ "name": textLike("m") });
5
votes for the like-operator tag. Could I kindly request that you suggest sql-like as a synonym? – Kermit