[mongodb] Checking if a field contains a string

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?

This question is related to mongodb

The answer is


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/


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):

  • Regex (other answers) => 5.6-6.9 seconds
  • Text Search => .164-.201 seconds

Notes:

  • A collection can have only one text index. You can use a wildcard text index if you want to search any string field, like this: db.collection.createIndex( { "$**": "text" } ).
  • A text index can be large. It contains one index entry for each unique post-stemmed word in each indexed field for each document inserted.
  • A text index will take longer to build than a normal index.
  • A text index does not store phrases or information about the proximity of words in the documents. As a result, phrase queries will run much more effectively when the entire collection fits in RAM.

ideal answer its use index i option for case-insensitive

db.users.findOne({"username" : new RegExp(search_value, 'i') });

For aggregation framework


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' } }
    }
])

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="/wiki/Felidae" title="Felidae">cat</a> <a href="/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="/wiki/Panthera" title="Panthera">Panthera</a></i> with the <a href="/wiki/Lion" title="Lion">lion</a>, <a href="/wiki/Leopard" title="Leopard">leopard</a>, <a href="/wiki/Jaguar" title="Jaguar">jaguar</a>, and <a href="/wiki/Snow_leopard" title="Snow leopard">snow leopard</a>. It is an <a href="/wiki/Apex_predator" title="Apex predator">apex predator</a>, primarily preying on <a href="/wiki/Ungulate" title="Ungulate">ungulates</a> such as <a href="/wiki/Deer" title="Deer">deer</a> and <a href="/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.


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


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.


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})

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


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.