Docs Menu
Docs Home
/ / /
Rust Driver
/ / /

Specify a Query

On this page

  • Overview
  • Sample Data
  • Literal Values
  • Comparison
  • Logical
  • Element
  • Evaluation
  • Bitwise
  • Array
  • Additional Information

In this guide, you can learn how to specify a query to match a subset of documents.

To match a subset of documents, specify a query filter containing your match criteria. Match criteria consist of the fields and values you want documents to match. A query filter contains at least one set of match criteria to determine which documents to return. If you use an empty query filter in a find operation, the driver matches all the documents in the collection.

In a query filter, you can match fields with literal values or with query operators. Query operators allow you to perform mathematical or logical operations to locate documents within a collection.

To match documents by using literal values, use the following format:

let filter = doc! { "<field>": "<value>" };

To create match criteria that include query operators, use the following format:

let filter = doc! { "<field>": doc! { "<operator>": "<value>" } };

The examples in the following sections show how to specify queries by using the find() method to match documents in a collection.

This guide includes the following sections:

  • Sample Data for Examples presents the sample data that is used by the query examples

  • Literal Values describes how to query for data that exactly matches a value you provide in the query filter

  • Comparison describes how to query for data based on comparisons with values in a collection

  • Logical describes how to query for data using logic applied to the results of field-level operators

  • Element describes how to query based on the presence, absence, or type of field

  • Evaluation describes how to execute higher-level logic, like regex and text searches, when querying for documents in a collection

  • Bitwise describes how to query based on the equivalent bits set of a base-10 value

  • Array describes how to query a collection based on data within an array-valued field

  • Additional Information provides links to resources and API documentation for types and methods mentioned in this guide

The examples in this guide use the following sample documents. Each document represents a fruit in a store's inventory and contains information about its quantity. Some documents contain fields that describe the fruit or its vendors.

#[derive(Serialize, Deserialize, Debug)]
struct Fruit {
_id: String,
name: String,
quantity: i32,
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
vendors: Option<Vec<String>>
}

The examples in the following sections query a collection of documents described by Fruit structs:

let docs = vec! [
Fruit {
_id: 1.to_string(),
name: "orange".to_string(),
quantity: 7,
description: None,
vendors: None
},
Fruit {
_id: 2.to_string(),
name: "apple".to_string(),
quantity: 4,
description: Some("Granny Smith".to_string()),
vendors: None
},
Fruit {
_id: 3.to_string(),
name: "banana".to_string(),
quantity: 36,
description: None,
vendors: None
},
Fruit {
_id: 4.to_string(),
name: "pear".to_string(),
quantity: 28,
description: None,
vendors: vec!["A".to_string(), "C".to_string() ].into()
},
];

To learn how to insert this data into a collection, see the Insert Documents guide.

Literal value query filters allow you to query for data that exactly matches a value you provide in the query filter. The following operation uses a literal query to search for documents containing a field called name that has the value of "pear":

let query = doc! { "name": "pear" };
let mut cursor = my_coll.find(query).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Fruit { _id: "4", name: "pear", quantity: 28, description: None, vendors: Some(["A", "C"]) }

Note

Literal value queries function identically to queries that use the $eq comparison operator. For example, the following queries are equivalent:

my_coll.find(doc! {
"price": doc! { "$eq": 5 }
}).await?;
my_coll.find(doc! {
"price": 5
}).await?;

Comparison operators allow you to query for documents by comparing them to values in the query filter. Common comparison operators include $gt for "greater than" comparisons, $lt for "less than" comparisons, and $ne for "not equal to" comparisons.

The following operation uses the comparison operator $gt to match documents with a quantity value greater than 5:

// $gt means "greater than"
let query = doc! { "quantity": doc! { "$gt": 5 } };
let mut cursor = my_coll.find(query).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Fruit { _id: "1", name: "orange", quantity: 7, description: None, vendors: None }
Fruit { _id: "3", name: "banana", quantity: 36, description: None, vendors: None }
Fruit { _id: "4", name: "pear", quantity: 28, description: None, vendors: Some(["A", "C"]) }

For more information on comparison operators, see Comparison Query Operators in the Server manual.

Logical operators require at least two match criteria and can match documents that meet some, all, or none of these criteria. For example, you can use the logical operator $or to query for documents that match either a $gt (greater than) comparison operator or a literal value query.

The following operation uses the logical operator $and to match documents with a quantity value that is greater than 10 and divisible by 3:

let query =
doc! { "$and": [
doc! { "quantity": doc! { "$gt": 10 } },
doc! { "quantity": doc! { "$mod": [ 3, 0 ] } }
]
};
let mut cursor = my_coll.find(query).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Fruit { _id: "3", name: "banana", quantity: 36, description: None, vendors: None }

Note

If a query filter contains a literal value query with multiple field-value pairs, the driver matches documents that meet all the criteria.

For example, the following queries produce equivalent results:

my_coll.find(doc! {
"price": doc! { "$eq": 5 },
"quantity": doc! { "$gt": 4 }
});
my_coll.find(doc! {
"$and": [
doc! { "price": { "$eq": 5 }},
doc! { "quantity": { "$gt": 4 }}
]
});

For a full list of logical operators, see Logical Query Operators in the Server manual.

Element operators allow you to match documents based on the types of specified fields or if they include specified fields.

The following operation uses the element operator $exists to search for documents containing the description field:

let query = doc! { "description": doc! { "$exists": true } };
let mut cursor = my_coll.find(query).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Fruit { _id: "2", name: "apple", quantity: 4, description: Some("Granny Smith"),
vendors: None }

Note

The Fruit struct describing the documents in this guide uses the #[serde(skip_serializing_if = "Option::is_none")] attribute on two of its fields. This attribute specifies that the field be ignored if its value is None. This prevents a description value of None from being returned on an $exists query.

See the serialize_with Serde attribute for more information.

For a full list of element operators, see Element Query Operators in the Server manual.

Evaluation operators analyze individual fields or a collection's documents to determine if they meet certain criteria. Each evaluation operator performs a different function. For example, the $mod operator performs a mathematical operation on a field value, and the $where operator allows you to evaluate values against JavaScript expressions.

The following operation uses the evaluation operator $mod to search for documents with a quantity value that is divisible by 3:

// $mod means "modulo" and checks if the remainder is a specific value
let query = doc! { "quantity": doc! { "$mod": [ 3, 0 ] } };
let mut cursor = my_coll.find(query).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Fruit { _id: "3", name: "banana", quantity: 36, description: None, vendors: None }

For a full list of evaluation operators, see Evaluation Query Operators in the Server manual.

Bitwise operators convert a numeric field from a base-10 (decimal) number into the corresponding base-2 (binary) number. They check whether the value in a document has the same bits set as the value in your match criteria.

The following example matches documents where the quantity has the same bits set as 7, which is equivalent to 00000111 in binary:

let query = doc! { "quantity": doc! { "$bitsAllSet": 7 } };
let mut cursor = my_coll.find(query).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Fruit { _id: "1", name: "orange", quantity: 7, description: None, vendors: None }

For a full list of bitwise operators, see Bitwise Query Operators in the Server manual.

Array operators check the values or amount of elements in an array-valued field.

The following example matches documents where the vendor array field contains "C":

let query = doc! { "vendors": doc! { "$elemMatch": { "$eq": "C" } } };
let mut cursor = my_coll.find(query).await?;
while let Some(doc) = cursor.try_next().await? {
println!("{:?}", doc);
}
Fruit { _id: "4", name: "pear", quantity: 28, description: None, vendors: Some(["A", "C"]) }

For a full list of bitwise operators, see Array Query Operators in the Server manual.

To learn more about find operations, see the Retrieve Data guide.

To learn more about query operators, see Query Selectors in the Server manual.

To learn more about the methods and types used in this guide, see the following API documentation:

Back

Retrieve Data