How to Query for a Portion of a String in a MongoDB Document
This is going to be a very important guide and that's because this is going to be one of the guides we're get into some very similar code that you're going to see in production applications that use Mongo.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

We're going to insert a new book and this one has a much longer title, It's called "Deep Work: Rules for Focus Success in a Distracted World". Now what we've done so far in regards to querying is all of those searches that we've done have required an exact match which means that if we wanted to run a query for this book we would need to take the exact title and plug that into the query. And that is not something that you're usually going to do in a real application. Instead, you're going to implement what's called a regular expression, and then you're going to match for something similar. So let's go in and we're going to add this into the database.

large

And so that got inserted. And now what we're going to do is build out that query the one that uses regular expressions. So I can say db.books. findOne. If you remember back. So we just want to find one item that matches here. And then inside of this, we're going to pass in an object just like we've done before but now we're going to pass in a regular expression. So we're going to pass in this forward slash followed by a dot followed by an asterisk and then we're going to put in the pattern we're looking for, here we're looking for deep work followed by a dot followed by another Asterix followed by a slash and then the letter I and that is the object

db.books.findOne({ name: /.*deep work.*/i })

and let's run it and see if this works.

Then we'll take a step back and analyze the entire expression. So you can see that that worked

large

If we would have done that with just the regular find and then the name it would not have worked. Just so you trust me on that one, I'm going to test it out. So we're in a deep work just with the text by itself. And now if I run this it returns NULL which means it couldn't find anything.

db.books.findOne({ name: 'deep work' })
null

What exactly is happening here? Well, the first part is to have the slashes (//) because what these slashes do and this is pretty much common in just about every programming language I've ever worked in is whenever you see text in between slashes. That typically means it's going to be a regular expression and that it's trying to match a pattern in a string. So with our dot and asterisk here what we're saying is regardless if this content is at the beginning the middle or the end. I want you to bring back anything that matches this set of values now where the i comes in, this part is pretty cool. The i makes it case insensitive that means that deep work if you notice it's capitalized at the top. And so with what the i allows us to do is just ignore what is capital or not capital. And it simply runs a query and returns back any of the documents that match that particular pattern.

This is a very popular thing that you're going to be implementing whenever you're building out a query engine. Imagine a search engine through your documents. You don't want to care about if someone typed in is the right thing whether it's capitalized or not and you don't want to care if they put maybe not enough words and if they didn't type this entire title out you don't want to require that in order for them to bring back this book. A pretty common practice would be to just type a few keywords in and then it runs the query and then returns back what they're looking for.

Now, Regular expressions are a massive topic and there are entire books and courses dedicated just to regular expressions so I definitely recommend for you if you're interested to look into that more. But as far as a basic regular expression implementation this will work in many cases where you just want to slide of view patterns in such as a few words and then make sure that if those match it brings back the query.

Code

db.books.findOne({ name: /.*deep work.*/i })
db.books.insert({
    "name": "Deep Work: Rules for Focused Success in a Distracted World",
    "publishedDate": new Date(),
    "authors": [
        {"name": "Cal Newport"}
    ]
});