DEV Community

Cover image for Learn MongoDB: Query Documents - I
Paras 🧙‍♂️
Paras 🧙‍♂️

Posted on • Updated on

Learn MongoDB: Query Documents - I

Reading or Finding document/s is one important operation. In MongoDB, there is a good amount of things that we have to learn to find the data we need. In this post, I will cover all kind of operators that mongodb has to offer for querying documents.

For setting up mongodb, you can checkout my getting started post or official docs.


Table of Content:


Read Methods

We have two read methods when it comes to querying data.

  • find
  • findOne

In this post we will use find because results are same for both and the only difference is findOne returns only the first document from the matched results.

Again, we will work with the pokeworld db that we created in previous post.


New Document Structure in pokemons collection

{
   name: "pikachu",
   type: "Electric",
   stats: {
     health: 40,
     attack: 50,
     defense: 45
   },
   level: 16,
   weakness: "ground", // this field can be empty in some documents
   evolution: "raichu",
   moves: [
      {name: "quick attack", dmg: 40},
      {name: "thunder bolt", dmg: 90},
      {name: "irontail", dmg: 50}
   ]
}
Enter fullscreen mode Exit fullscreen mode

This document structure should be enough to help us learn different ways of querying data. Let's begin !

Simple Query

# find grass type pokemon with level 20
> db.pokemons.find({type: "Grass", level: 40}).pretty()
Enter fullscreen mode Exit fullscreen mode

Query Embedded Documents

Embedded documents are objects inside a document. E.g. stats field in our document. Use quotes and . dot to query fields inside an embedded documents.

# find electric pokemon with health 40
> db.pokemons.find({type: "Electric", "stats.health": 40}).pretty()
Enter fullscreen mode Exit fullscreen mode

pretty() method helps you format document in shell to make the results readable.

Finding documents using operators

When it comes to querying data in a more refined way, we need more than just simple queries. That's mongo has operators that help us in building more advance queries.

Types of Operators:

  • Query Operators (Used to find data)
  • Projection Operators (Modify the presentation of documents)
  • Update Operators (Update or add data to documents)

We will work with Query Operators in this post. There are different types of Query operators that are available to us.

  • Comparision Operators
  • Logical Operators
  • Element Query Operators
  • Evaluation Query Operators (in next post)
  • Geospatial Operators (in next post)
  • Array Operators (in next post)

Comparision Operators

When we want to compare data in documents, like less than, greater than, not equal, then we use comparision operators.

  • Operators: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin
# $eq, no need in simple queries
> db.pokemons.find({$eq: {"name": "pikachu"}})

# $ne(not equal), get pokemons with health not equal to 40
> db.pokemons.find({"stats.attack": {$ne: 40}})

# $gt(greater), $gte(greater than equal), 
# $lt(less than), $lte(less than equal)
> db.pokemons.find({type: "grass", "stats.health": {$gte: 40, $lt: 60}})

# $in(includes), $nin(not includes)
# find pokemons that have following healths: 40, 45, 50
> db.pokemons.find({"stats.health": {$in: [40, 50, 45]}})
Enter fullscreen mode Exit fullscreen mode

Logical Operators

Logical operators help us build logical statements e.g. AND, OR, NOR, NOT

  • Operators: $and, $or, $nor, $not

$or : It helps us when we want one of the condition to be true. We pass the 2 or more filters in an array when using this operator.

$nor : It is just the opposite of $or and can be used in a similar way to perform the opposite of $or

# find pokemon with type grass or electric and health 40
> db.pokemons.find({
   health: 40, 
   $or: [
      {type: "grass"},
      {type: "electric"}
   ]
})
Enter fullscreen mode Exit fullscreen mode

$and : $and also takes an array of filters and checks if all the conditions are fulfilled by a document or not.

# find pokemons with health 40 and attack 60
> db.pokemons.find({
   $and: [
       {"stats.health": 40},
       {"stats.attack": 60}
   ]
})
Enter fullscreen mode Exit fullscreen mode

$not : $not is used when you want to negate a filter i.e. do the opposite of what the filter is doing.

# find pokemons with defense not greater than 45
> db.pokemons.find({ "stats.defense": {$not: {$gt: 45}} })

# you can use $eq operator with $not for "not equal" case.
Enter fullscreen mode Exit fullscreen mode

Element Operators

There are two element operators. They help us work with fields and not data. By this I mean, the fields e.g. stats, type, fields in a pokemon document.

  • Operators: $exists, $type

$exists : Because the structure of a mongodb document is not rigid, and can omit some fields in some documents, we sometime needs to check if a field exists in a document or not. This is when $exists operator comes in action.

If you check the example document structure I given at the start, you will see that weakness field can be empty in some documents i.e. it doesn't exists in some documents (some kind of super pokemons with no weakness :p )

# find pokemons who have weakness field/key
> db.pokemons.find({ weakness: {$exists: true}})
Enter fullscreen mode Exit fullscreen mode

$type : This operator helps us check the type of field in a document. Let's learn about the available types in mongoDB, so that we can use this operators in a better way. (I will list the important and most used ones. For complete list, you can check here)

  • Number types: "int", "long", "decimal", "double"
  • Boolean types: "bool"
  • Date types: "date", "timestamp"
  • String types: "string"
  • Object types: "object"
  • Array types: "array"
  • Object Id: "objectId"
  • Null type: "null"
  • Binary data type: "binData"
# Suppose you inserted a pokemon in collection
# Instead of numbers, you inserted them as string !
# let's find those docs !!
> db.pokemons.find({"stats.health": {$type: "string"}})
Enter fullscreen mode Exit fullscreen mode

By default, when storing numbers, mongodb uses "double" type.


That was a lot, I think. We learned many important and useful operators that we need to query our data in mongodb. In next post, I will cover the rest of the operators (evaluation and array operators).

So, that's it for now ! Hope this series is helping you.

If you got any suggestion, feel free to tell me in comments :)

Next Post : Query Documents - Part II

Prev Post : Basic CRUD Operations

Top comments (0)