指定查询
概述
在这份指南中,您可以学习如何指定一个查询以匹配文档的子集。
要匹配文档的子集,请指定包含您的匹配条件的 查询过滤器。匹配条件包括您希望文档匹配的字段和值。查询过滤器包含至少一组匹配条件,以确定要返回哪些文档。如果您在查找操作中使用空查询过滤器,驱动程序将匹配集合中所有文档。
在查询过滤器中,您可以使用字面值或查询运算符来匹配字段。查询运算符允许您在集合中执行数学或逻辑操作以定位文档。
要使用字面值匹配文档,请使用以下格式
let filter = doc! { "<field>": "<value>" };
要创建包含查询运算符的匹配条件,请使用以下格式
let filter = doc! { "<field>": doc! { "<operator>": "<value>" } };
以下章节中的示例显示了如何使用find()
方法通过匹配集合中的文档来指定查询。
本指南包括以下章节
示例数据
本指南中的示例使用以下示例文档。每个文档代表商店库存中的水果,并包含其数量信息。一些文档包含描述水果或其供应商的字段。
struct Fruit { _id: String, name: String, quantity: i32, description: Option<String>, vendors: Option<Vec<String>> }
以下部分中的示例查询由 Fruit
结构体描述的文档集合
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() }, ];
有关如何将此数据插入到集合中的说明,请参阅插入文档指南。
字面量值
字面量值查询过滤器允许您查询与查询过滤器中提供的值完全匹配的数据。以下操作使用字面量查询搜索包含名为 name
的字段,其值为 "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"]) }
注意
字面量值查询与使用 $eq
比较运算符的查询功能相同。例如,以下查询是等效的
my_coll.find(doc! { "price": doc! { "$eq": 5 } }).await?;
my_coll.find(doc! { "price": 5 }).await?;
比较
比较运算符允许您通过将文档与查询过滤器中的值进行比较来查询文档。常见的比较运算符包括 $gt
(大于),$lt
(小于)和 $ne
(不等于)。
示例
以下操作使用比较运算符 $gt
来匹配具有 quantity
值大于 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"]) }
有关比较运算符的更多信息,请参阅服务器手册中的 比较查询运算符。
逻辑
逻辑运算符至少需要两个匹配条件,可以匹配满足一些、所有或没有任何这些条件的文档。例如,您可以使用逻辑运算符 $or
来查询匹配 $gt
(大于)比较运算符或字面值查询的文档。
示例
以下操作使用逻辑运算符$and
匹配具有大于10
且能被3
整除的quantity
值的文档。
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 }
注意
如果一个查询过滤器包含多个字段-值对的字面值查询,驱动程序将匹配满足所有条件的文档。
例如,以下查询产生等效的结果
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 }} ] });
有关逻辑运算符的完整列表,请参阅服务器手册中的逻辑查询运算符。
元素
元素运算符允许您根据指定的字段类型或是否包含指定的字段来匹配文档。
示例
以下操作使用元素运算符$exists
来搜索包含description
字段的文档。
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 }
注意
本指南中描述文档的 水果结构 使用了两个字段上的 #[serde(skip_serializing_if = "Option::is_none")]
属性。此属性指定当字段的值为 None
时,应忽略该字段。这可以防止在 $exists
查询中返回 description
值为 None
。
有关更多信息,请参阅 serialize_with Serde 属性。
有关元素操作符的完整列表,请参阅服务器手册中的 元素查询操作符。
评估
评估操作符分析单个字段或集合文档,以确定它们是否符合某些标准。每个评估操作符执行不同的功能。例如,$mod
操作符对一个字段值执行数学运算,而 $where
操作符允许您使用 JavaScript 表达式评估值。
示例
以下操作使用评估运算符 $mod
搜索具有能被3整除的 quantity
值的文档
// $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 }
有关评估运算符的完整列表,请参阅服务器手册中的评估查询运算符。
位运算
位运算符将数字字段从十进制(基数-10)转换为相应的二进制(基数-2)数。它们检查文档中的值是否与匹配条件中的值具有相同的位。
示例
以下示例匹配具有与 7
相同位的 quantity
的文档,这在二进制中表示为 00000111
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 }
有关位运算符的完整列表,请参阅服务器手册中的位查询运算符。
数组
数组操作符检查数组值字段中的值或元素数量。
示例
以下示例匹配包含 "C"
的 vendor
数组字段的文档。
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"]) }
有关位运算符的完整列表,请参阅服务器手册中的数组查询运算符。
更多信息
要了解更多关于查找操作的信息,请参阅检索数据指南。
要了解更多关于查询运算符的信息,请参阅服务器手册中的查询选择器。
API 文档
要了解本指南中使用的方法和类型,请参阅以下 API 文档