I'm looking for an operator, which allows me to check, if the value of a field contains a certain string.
Something like:
db.users.findOne({$contains:{"username":"son"}})
Is that possible?
You can do it with the following code.
db.users.findOne({"username" : {$regex : "son"}});
$regex documentation page you linked and the information on Index Use. The best case regex search would be case-sensitive prefix scan; searches for non-prefix substrings or with case-insensitive options are not going to result in effective index usage. This is probably fine for small indexes, but extensive use of non-prefix regexes will affect performance for queries against larger indexes.As Mongo shell support regex, that's completely possible.
db.users.findOne({"username" : /.*son.*/});
If we want the query to be case-insensitive, we can use "i" option, like shown below:
db.users.findOne({"username" : /.*son.*/i});
See: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions
db.users.findOne({"username" : /.*son.*/}); could also be overkill and the regex could simple be /son/{ username: /son/ }https://docs.mongodb.com/manual/reference/sql-comparison/
http://php.net/manual/en/mongo.sqltomongo.php
MySQL
SELECT * FROM users WHERE username LIKE "%Son%"
MongoDB
db.users.find({username:/Son/})
As of version 2.4, you can create a text index on the field(s) to search and use the $text operator for querying.
First, create the index:
db.users.createIndex( { "username": "text" } )
Then, to search:
db.users.find( { $text: { $search: "son" } } )
Benchmarks (~150K documents):
Notes:
db.collection.createIndex( { "$**": "text" } )
As this is one of the first hits in the search engines, and none of the above seems to work for MongoDB 3.x, here is one regex search that does work:
db.users.find( { 'name' : { '$regex' : yourvalue, '$options' : 'i' } } )
No need to create and extra index or alike.
i is for "Case insensitivity to match upper and lower cases."Here's what you have to do if you are connecting MongoDB through Python
db.users.find({"username": {'$regex' : '.*' + 'Son' + '.*'}})
you may also use a variable name instead of 'Son' and therefore the string concatenation.
Simplest way to accomplish this task
If you want the query to be case-sensitive
db.getCollection("users").find({'username':/Son/})
If you want the query to be case-insensitive
db.getCollection("users").find({'username':/Son/i})
/ symbols instead of ' or " for strings).new RegExp(variable)ideal answer its use index i option for case-insensitive
db.users.findOne({"username" : new RegExp(search_value, 'i') });
This should do the work
db.users.find({ username: { $in: [ /son/i ] } });
The i is just there to prevent restrictions of matching single cases of letters.
You can check the $regex documentation on MongoDB documentation.
Here's a link: https://docs.mongodb.com/manual/reference/operator/query/regex/
If you need to do the search for more than one attribute you can use the $or. For example
Symbol.find(
{
$or: [
{ 'symbol': { '$regex': input, '$options': 'i' } },
{ 'name': { '$regex': input, '$options': 'i' } }
]
}
).then((data) => {
console.log(data)
}).catch((err) => {
console.log(err)
})
Here you are basing your search on if the input is contained in the symbol attribute or the name attribute.
If the regex is not working in your Aggregate solution and you have nested object. Try this aggregation pipeline: (If your object structure is simple then, just remove the other conditions from below query):
db.user.aggregate({$match:
{$and:[
{"UserObject.Personal.Status":"ACTV"},
{"UserObject.Personal.Address.Home.Type":"HME"},
{"UserObject.Personal.Address.Home.Value": /.*son.*/ }
]}}
)
One other way would be to directly query like this:
db.user.findOne({"UserObject.Personal.Address.Home.Value": /.*son.*/ });
Field search
('$options': 'i' for case insensitive search)
db.users.aggregate([
{
$match: {
'email': { '$regex': '@gmail.com', '$options': 'i' }
}
}
]);
Full document search
(only works on fields indexed with a text index
db.articles.aggregate([
{
$match: { $text: { $search: 'brave new world' } }
}
])
If your regex includes a variable, make sure to escape it.
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
This can be used like this
new RegExp(escapeRegExp(searchString), 'i')
Or in a mongoDb query like this
{ '$regex': escapeRegExp(searchString) }
Posted same comment here
How to ignore HTML tags in a RegExp match:
var text = '<p>The <b>tiger</b> (<i>Panthera tigris</i>) is the largest <a href="https://stackoverflow.com/wiki/Felidae" title="Felidae">cat</a> <a href="https://stackoverflow.com/wiki/Species" title="Species">species</a>, most recognizable for its pattern of dark vertical stripes on reddish-orange fur with a lighter underside. The species is classified in the genus <i><a href="https://stackoverflow.com/wiki/Panthera" title="Panthera">Panthera</a></i> with the <a href="https://stackoverflow.com/wiki/Lion" title="Lion">lion</a>, <a href="https://stackoverflow.com/wiki/Leopard" title="Leopard">leopard</a>, <a href="https://stackoverflow.com/wiki/Jaguar" title="Jaguar">jaguar</a>, and <a href="https://stackoverflow.com/wiki/Snow_leopard" title="Snow leopard">snow leopard</a>. It is an <a href="https://stackoverflow.com/wiki/Apex_predator" title="Apex predator">apex predator</a>, primarily preying on <a href="https://stackoverflow.com/wiki/Ungulate" title="Ungulate">ungulates</a> such as <a href="https://stackoverflow.com/wiki/Deer" title="Deer">deer</a> and <a href="https://stackoverflow.com/wiki/Bovid" class="mw-redirect" title="Bovid">bovids</a>.</p>';
var searchString = 'largest cat species';
var rx = '';
searchString.split(' ').forEach(e => {
rx += '('+e+')((?:\\s*(?:<\/?\\w[^<>]*>)?\\s*)*)';
});
rx = new RegExp(rx, 'igm');
console.log(text.match(rx));
This is probably very easy to turn into a MongoDB aggregation filter.
MongoDB 4.2 onwards a new aggregate operator introduced called $regexMatch.
While the $regex operator was usable only inside $match stage, the $regexMatch operator can be used with other aggregate stages.
Example: Here we use $project stage that adds an additional field called "usernameMatches". It's value is true if the $regexMatch satisfies the condition or else false.
db.users.aggregate([
{
$project: {
usernameMatches: {
$regexMatch: {
input: "$username",
regex: /son/,
options: "i"
}
},
username: 1
}
}
]);
Output:-
[
{
_id: "6307353fa2312096b171fe78"
usernname: "johnson"
usernameMatches: true
},
{
_id: "6307353fa2312096b171fe79"
usernname: "alex"
usernameMatches: false
}
.
.
.
]
Similarly 2 additional operators $regexFind and $regexFindAll introduced from 4.2 onward.