Read Data using Operators and Compound Queries
Overview
In the previous read guide, Read Data from MongoDB With Queries, you read data using equality queries. In this guide, you will:
Read data from the
sample_guides.planets
collection with MongoDB's comparison operators.Combine query criteria to make compound queries.
Use dot notation to query embedded fields.
Time required: 20 minutes
What You'll Need
A connection string to your MongoDB deployment.
Sample datasets loaded into your cluster.
Procedure
Read Data with Embedded Fields and Comparison Operators
In this exercise, you will read data using comparison operators.
Connect to your MongoDB instance.
Tip
The following is an outline with the minimum code necessary to connect to MongoDB. You'll make additions over the next few steps to read data.
At line 5, replace the URI string with your own Atlas connection string.
1 using MongoDB.Bson;
2 using MongoDB.Driver;
3
4 // Replace the uri string with your MongoDB deployment's connection string.
5 var uri = "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority";
6
7 var client = new MongoClient(uri);
8
9 var coll = client.GetDatabase("sample_guides").GetCollection<BsonDocument>("planets");
10 // find code goes here
11 var cursor = coll.AsQueryable();
12
13 foreach (var document in cursor)
14 {
15 Console.WriteLine(document);
16 }
Tip
The following is an outline with the minimum code necessary to connect to MongoDB. You'll make additions over the next few steps to read data.
At line 13, replace the URI string with your own Atlas connection string.
1 package main 2 3 import ( 4 "context" 5 "fmt" 6 7 "go.mongodb.org/mongo-driver/bson" 8 "go.mongodb.org/mongo-driver/mongo" 9 "go.mongodb.org/mongo-driver/mongo/options" 10 ) 11 12 func main() { 13 uri := "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority" 14 15 client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri)) 16 if err != nil { 17 panic(err) 18 } 19 20 defer func() { 21 if err = client.Disconnect(context.TODO()); err != nil { 22 panic(err) 23 } 24 }() 25 coll := client.Database("sample_guides").Collection("planets") 26 27 // find code goes here 28 filter := bson.D{{}} 29 cursor, err := coll.Find(context.TODO(), filter) 30 if err != nil { 31 panic(err) 32 } 33 34 for cursor.Next(context.TODO()) { 35 var result bson.M 36 if err := cursor.Decode(&result); err != nil { 37 panic(err) 38 } 39 fmt.Println(result) 40 } 41 if err := cursor.Err(); err != nil { 42 panic(err) 43 } 44 }
Tip
The following is an outline with the minimum code necessary to connect to MongoDB. You'll make additions over the next few steps to read data.
At line 8, replace the URI string with your own Atlas connection string.
1 import com.mongodb.client.*; 2 import com.mongodb.client.model.Filters.*; 3 import org.bson.Document; 4 import org.bson.conversions.Bson; 5 6 public class CrudRead { 7 public static void main(String[] args) { 8 String uri = "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority"; 9 10 try (MongoClient mongoClient = MongoClients.create(uri)) { 11 MongoCollection<Document> coll = mongoClient.getDatabase("sample_guides") 12 .getCollection("planets"); 13 // find code goes here 14 Bson filter = Filters.empty(); 15 MongoCursor<Document> cursor = coll.find(filter).iterator(); 16 try { 17 while (cursor.hasNext()) { 18 System.out.println(cursor.next().toJson()); 19 } 20 } finally { 21 cursor.close(); 22 } 23 } 24 } 25 }
Tip
The following is an outline with the minimum code necessary to connect to MongoDB. You'll make additions over the next few steps to read data.
At line 4, replace the URI string with your own Atlas connection string.
1 const { MongoClient } = require("mongodb"); 2 // Replace the uri string with your MongoDB deployment's connection string. 3 const uri = 4 "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority"; 5 const client = new MongoClient(uri); 6 async function run() { 7 try { 8 await client.connect(); 9 const coll = client.db("sample_guides").collection("planets"); 10 11 // find code goes here 12 let cursor = coll.find(); 13 14 await cursor.forEach(console.log); 15 } finally { 16 // Ensures that the client will close when you finish/error 17 await client.close(); 18 } 19 } 20 run().catch(console.dir);
Tip
The following is an outline with the minimum code necessary to connect to MongoDB. You'll make additions over the next few steps to read data.
At line 4, replace the URI string with your own Atlas connection string.
1 from pymongo import MongoClient 2 3 # Replace the uri string with your MongoDB deployment's connection string. 4 uri = "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority" 5 6 client = MongoClient(uri) 7 coll = client.sample_guides.planets 8 9 # find code goes here 10 cursor = coll.find() 11 12 for doc in cursor: 13 print(doc) 14 15 # Close the connection to MongoDB when you're done. 16 client.close()
Tip
mongodb+srv
Make sure you've installed PyMongo with the srv
option.
python3 -m pip install "pymongo[srv]"
Select documents using the less-than operator.
Use dot notation
in this query to select documents where the embedded document surfaceTemperatureC
has a value in its mean
field less than 15 degrees (Celsius).
// find code goes here
var cursor = from planet in coll.AsQueryable()
where planet["surfaceTemperatureC.mean"] < 15
select planet;
1 // find code goes here 2 filter := bson.D{{"surfaceTemperatureC.mean", bson.D{{"$lt", 15}}}} 3 cursor, err := coll.Find(context.TODO(), filter) 4 if err != nil { 5 panic(err) 6 }
The MongoDB Java Driver includes
Builders
that simplify the process of creating queries (and other operations).
Here, you use the Filters.lt
builder to construct the query document.
1 // find code goes here 2 Bson filter = lt("surfaceTemperatureC.mean", 15); 3 MongoCursor<Document> cursor = coll.find(filter).iterator();
// find code goes here const cursor = coll.find({ "surfaceTemperatureC.mean": { $lt: 15 } });
# find code goes here cursor = coll.find({"surfaceTemperatureC.mean": {"$lt": 15}})
Check your results.
Here is the complete code followed by sample output. Results have been truncated for display purposes.
1 using MongoDB.Bson;
2 using MongoDB.Driver;
3
4 // Replace the uri string with your MongoDB deployment's connection string.
5 var uri = "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority";
6
7 var client = new MongoClient(uri);
8
9 var coll = client.GetDatabase("sample_guides").GetCollection<BsonDocument>("planets");
10 // find code goes here
11 var cursor = from planet in coll.AsQueryable()
12 where planet["surfaceTemperatureC.mean"] < 15
13 select planet;
14
15 foreach (var document in cursor)
16 {
17 Console.WriteLine(document);
18 }
{ "name" : "Uranus", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -197.19999999999999 }, ... } { "name" : "Mars", "surfaceTemperatureC" : { "min" : -143, "max" : 35, "mean" : -63 }, ... } { "name" : "Neptune", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -201 }, ... } { "name" : "Jupiter", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -145.15000000000001 }, ... } { "name" : "Earth", "surfaceTemperatureC" : { "min" : -89.200000000000003, "max" : 56.700000000000003, "mean" : 14 }, ... } { "name" : "Saturn", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -139.15000000000001 }, ... }
1 package main 2 3 import ( 4 "context" 5 "fmt" 6 7 "go.mongodb.org/mongo-driver/bson" 8 "go.mongodb.org/mongo-driver/mongo" 9 "go.mongodb.org/mongo-driver/mongo/options" 10 ) 11 12 func main() { 13 uri := "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority" 14 15 client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri)) 16 if err != nil { 17 panic(err) 18 } 19 20 defer func() { 21 if err = client.Disconnect(context.TODO()); err != nil { 22 panic(err) 23 } 24 }() 25 coll := client.Database("sample_guides").Collection("planets") 26 27 // find code goes here 28 filter := bson.D{{"surfaceTemperatureC.mean", bson.D{{"$lt", 15}}}} 29 cursor, err := coll.Find(context.TODO(), filter) 30 if err != nil { 31 panic(err) 32 } 33 34 for cursor.Next(context.TODO()) { 35 var result bson.M 36 if err := cursor.Decode(&result); err != nil { 37 panic(err) 38 } 39 fmt.Println(result) 40 } 41 if err := cursor.Err(); err != nil { 42 panic(err) 43 } 44 }
map[ name:Uranus surfaceTemperatureC:map[max:<nil> mean:-197.2 min:<nil>] ...] map[ name:Mars surfaceTemperatureC:map[max:35 mean:-63 min:-143] ... ] map[ name:Neptune surfaceTemperatureC:map[max:<nil> mean:-201 min:<nil>] ... ] map[ name:Jupiter surfaceTemperatureC:map[max:<nil> mean:-145.15 min:<nil>] ... ] map[ name:Earth surfaceTemperatureC:map[max:56.7 mean:14 min:-89.2]] map[ name:Saturn surfaceTemperatureC:map[max:<nil> mean:-139.15 min:<nil>] ... ]
1 import com.mongodb.client.*; 2 import com.mongodb.client.model.Filters.*; 3 import org.bson.Document; 4 import org.bson.conversions.Bson; 5 6 public class CrudRead { 7 public static void main(String[] args) { 8 String uri = "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority"; 9 10 try (MongoClient mongoClient = MongoClients.create(uri)) { 11 MongoCollection<Document> coll = mongoClient.getDatabase("sample_guides") 12 .getCollection("planets"); 13 14 // find code goes here 15 Bson filter = lt("surfaceTemperatureC.mean", 15); 16 MongoCursor<Document> cursor = coll.find(filter).iterator(); 17 18 // iterate code goes here 19 try { 20 while (cursor.hasNext()) { 21 System.out.println(cursor.next().toJson()); 22 } 23 } finally { 24 cursor.close(); 25 } 26 } 27 } 28 }
{ "name" : "Uranus", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -197.19999999999999 }, ... } { "name" : "Mars", "surfaceTemperatureC" : { "min" : -143, "max" : 35, "mean" : -63 }, ... } { "name" : "Neptune", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -201 }, ... } { "name" : "Jupiter", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -145.15000000000001 }, ... } { "name" : "Earth", "surfaceTemperatureC" : { "min" : -89.200000000000003, "max" : 56.700000000000003, "mean" : 14 }, ... } { "name" : "Saturn", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -139.15000000000001 }, ... }
1 const { MongoClient } = require("mongodb"); 2 // Replace the uri string with your MongoDB deployment's connection string. 3 const uri = 4 "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority"; 5 const client = new MongoClient(uri); 6 async function run() { 7 try { 8 await client.connect(); 9 const coll = client.db("sample_guides").collection("planets"); 10 11 // find code goes here 12 const cursor = coll.find({ "surfaceTemperatureC.mean": { $lt: 15 } }); 13 14 await cursor.forEach(console.log); 15 } finally { 16 // Ensures that the client will close when you finish/error 17 await client.close(); 18 } 19 } 20 run().catch(console.dir);
{ "name" : "Uranus", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -197.19999999999999 }, ... } { "name" : "Mars", "surfaceTemperatureC" : { "min" : -143, "max" : 35, "mean" : -63 }, ... } { "name" : "Neptune", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -201 }, ... } { "name" : "Jupiter", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -145.15000000000001 }, ... } { "name" : "Earth", "surfaceTemperatureC" : { "min" : -89.200000000000003, "max" : 56.700000000000003, "mean" : 14 }, ... } { "name" : "Saturn", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -139.15000000000001 }, ... }
1 from pymongo import MongoClient 2 3 # Replace the uri string with your MongoDB deployment's connection string. 4 uri = "mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority" 5 6 client = MongoClient(uri) 7 coll = client.sample_guides.planets 8 9 # find code goes here 10 cursor = coll.find({"surfaceTemperatureC.mean": {"$lt": 15}}) 11 12 for doc in cursor: 13 print(doc) 14 15 # Close the connection to MongoDB when you're done. 16 client.close()
{ "name" : "Uranus", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -197.19999999999999 }, ... } { "name" : "Mars", "surfaceTemperatureC" : { "min" : -143, "max" : 35, "mean" : -63 }, ... } { "name" : "Neptune", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -201 }, ... } { "name" : "Jupiter", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -145.15000000000001 }, ... } { "name" : "Earth", "surfaceTemperatureC" : { "min" : -89.200000000000003, "max" : 56.700000000000003, "mean" : 14 }, ... } { "name" : "Saturn", "surfaceTemperatureC" : { "min" : null, "max" : null, "mean" : -139.15000000000001 }, ... }
Read Data with Compound Queries
Now you will read data from MongoDB using AND and OR logic to form compound queries.
Write an AND query.
To write a compound query in MongoDB that matches all of the query predicates (i.e. a logical AND), specify all of the fields that you wish to match in your find document. By default, MongoDB matches all of the fields. If you followed the previous guide you've already done this!
The following example retrieves all documents in the planets
collection where the surfaceTemperatureC.mean
field is less than 15
and the surfaceTemperatureC.min
field is greater than -100
.
1 // find code goes here
2 var cursor = from planet in coll.AsQueryable()
3 where planet["surfaceTemperatureC.mean"] < 15 && planet["surfaceTemperatureC.min"] > -100
4 select planet;
5
{'name': 'Earth', 'orderFromSun': 3, ...}
1 // find code goes here 2 filter := bson.D{ 3 {"$and", 4 bson.A{ 5 bson.D{{"surfaceTemperatureC.mean", 6 bson.D{{"$lt", 15}}, 7 }}, 8 bson.D{{"surfaceTemperatureC.min", 9 bson.D{{"$gt", -100}}, 10 }}, 11 }, 12 }, 13 } 14 cursor, err := coll.Find(context.TODO(), filter) 15 if err != nil { 16 panic(err) 17 }
map[name:Earth orderFromSun:3 ...]
1 // find code goes here 2 Bson filter = and(lt("surfaceTemperatureC.mean", 15), gt("surfaceTemperatureC.min", -100)); 3 MongoCursor<Document> cursor = coll.find(filter).iterator();
{'name': 'Earth', 'orderFromSun': 3, ...}
1 // find code goes here 2 const cursor = coll.find({ 3 "surfaceTemperatureC.mean": { $lt: 15 }, 4 "surfaceTemperatureC.min": { $gt: -100 }, 5 });
{'name': 'Earth', 'orderFromSun': 3, ...}
Note
Implicit AND
Specifying multiple criteria is common. If you don't specify any query operators, the driver interprets your criteria in an AND fashion. However, sometimes you must be explicit when specifying multiple criteria, particularly when specifying criteria on the same field.
For example, to find documents in the planets
collection that have
an orderFromSun
value greater than 2
AND less than 5
, you must
use the $and
query operator.
1 const cursor = coll.find({ 2 $and: [{ orderFromSun: { $gt: 2 } }, { orderFromSun: { $lt: 5 } }], 3 });
{'name': 'Mars', 'orderFromSun': 4, ... } {'name': 'Earth', 'orderFromSun': 3, ... }
1 cursor = coll.find( 2 {"$and": [{"orderFromSun": {"$gt": 2}}, {"orderFromSun": {"$lt": 5}}]} 3 )
{'name': 'Mars', 'orderFromSun': 4, ... } {'name': 'Earth', 'orderFromSun': 3, ... }
If you do not use the $and
operator, the driver encounters the
same key multiple times in the query filter, and uses the last
key encountered. Try omitting the $and
operator and see what
happens.
1 # find code goes here 2 cursor = coll.find( 3 {"surfaceTemperatureC.mean": {"$lt": 15}, "surfaceTemperatureC.min": {"$gt": -100}} 4 )
{'name': 'Earth', 'orderFromSun': 3, ...}
Note
Implicit AND
Specifying multiple criteria is common. If you don't specify any query operators, the driver interprets your criteria in an AND fashion. However, sometimes you must be explicit when specifying multiple criteria, particularly when specifying criteria on the same field.
For example, to find documents in the planets
collection that have
an orderFromSun
value greater than 2
AND less than 5
, you must
use the $and
query operator.
1 const cursor = coll.find({ 2 $and: [{ orderFromSun: { $gt: 2 } }, { orderFromSun: { $lt: 5 } }], 3 });
{'name': 'Mars', 'orderFromSun': 4, ... } {'name': 'Earth', 'orderFromSun': 3, ... }
1 cursor = coll.find( 2 {"$and": [{"orderFromSun": {"$gt": 2}}, {"orderFromSun": {"$lt": 5}}]} 3 )
{'name': 'Mars', 'orderFromSun': 4, ... } {'name': 'Earth', 'orderFromSun': 3, ... }
If you do not use the $and
operator, the driver encounters the
same key multiple times in the query filter, and uses the last
key encountered. Try omitting the $and
operator and see what
happens.
Write an OR query.
OR queries are required when you want to specify criteria that are
mutually exclusive. For example, you can't match documents in the
planets
collection where the orderFromSun
value is both
greater than 7
AND less than 2
.
The following example shows how to use the $or
operator to express
mutually exclusive criteria.
1 // find code goes here
2 var cursor = from planet in coll.AsQueryable()
3 where planet["orderFromSun"] > 7 || planet["orderFromSun"] < 2
4 select planet;
{ name: 'Mercury', orderFromSun: 1, ... } { name: 'Neptune', orderFromSun: 8, ... }
1 // find code goes here 2 filter := bson.D{ 3 {"$or", 4 bson.A{ 5 bson.D{{"orderFromSun", 6 bson.D{{"$gt", 7}}, 7 }}, 8 bson.D{{"orderFromSun", bson.D{{"$lt", 2}}}}, 9 }, 10 }, 11 } 12 13 cursor, err := coll.Find(context.TODO(), filter) 14 if err != nil { 15 panic(err) 16 }
map[name:Mercury orderFromSun:1 ...] map[name:Neptune orderFromSun:8 ...]
1 // find code goes here 2 Bson filter = or(gt("orderFromSun", 7), lt("orderFromSun", 2)); 3 MongoCursor<Document> cursor = coll.find(filter).iterator();
{ name: 'Mercury', orderFromSun: 1, ... } { name: 'Neptune', orderFromSun: 8, ... }
1 // find code goes here 2 const cursor = coll.find({ 3 $or: [{ orderFromSun: { $gt: 7 } }, { orderFromSun: { $lt: 2 } }], 4 });
{ name: 'Mercury', orderFromSun: 1, ... } { name: 'Neptune', orderFromSun: 8, ... }
1 # find code goes here 2 cursor = coll.find( 3 { 4 "$or": [ 5 {"orderFromSun": {"$gt": 7}}, 6 {"orderFromSun": {"$lt": 2}}, 7 ] 8 } 9 )
{ name: 'Mercury', orderFromSun: 1, ... } { name: 'Neptune', orderFromSun: 8, ... }
Summary
If you have successfully completed this guide, you have read data from MongoDB using MongoDB query operators and compound queries.
You can combine query operators in almost limitless ways to express complex queries. For example, you could query for documents that have rings AND a specific chemical compound in their atmosphere, or that are a specific temperature, AND all have the letter 'E' in their name.
In the next guide, you'll learn how to insert data into MongoDB.
See Also
The MongoDB C# Driver documentation
The MongoDB Go Driver documentation
The MongoDB Java(Sync) Driver documentation
The MongoDB Node.js Driver documentation
The PyMongo documentation