文档菜单
文档首页
/ / /
Rust 驱动
/ / /

指定查询

在本页

  • 概述
  • 示例数据
  • 字面值
  • 比较
  • 逻辑
  • 元素
  • 评估
  • 位运算
  • 数组
  • 更多信息

在这份指南中,您可以学习如何指定一个查询以匹配文档的子集。

要匹配文档的子集,请指定包含您的匹配条件的 查询过滤器。匹配条件包括您希望文档匹配的字段和值。查询过滤器包含至少一组匹配条件,以确定要返回哪些文档。如果您在查找操作中使用空查询过滤器,驱动程序将匹配集合中所有文档。

在查询过滤器中,您可以使用字面值或查询运算符来匹配字段。查询运算符允许您在集合中执行数学或逻辑操作以定位文档。

要使用字面值匹配文档,请使用以下格式

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

要创建包含查询运算符的匹配条件,请使用以下格式

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

以下章节中的示例显示了如何使用find() 方法通过匹配集合中的文档来指定查询。

本指南包括以下章节

  • 示例数据 展示了查询示例所使用的样本数据

  • 字面值 说明了如何查询与查询过滤器中提供的值完全匹配的数据

  • 比较 说明了如何基于与集合中值的比较来查询数据

  • 逻辑 说明了如何使用应用于字段级运算符结果的应用逻辑来查询数据

  • 元素 说明了如何基于字段的存在、不存在或类型进行查询

  • 评估 说明了在查询集合中的文档时如何执行高级逻辑,如正则表达式和文本搜索

  • 位运算 说明了如何基于十进制值的等效位集进行查询

  • 数组 说明了如何基于数组值字段中的数据查询集合

  • 更多信息 提供了本指南中提到的类型和方法的相关资源和API文档链接

本指南中的示例使用以下示例文档。每个文档代表商店库存中的水果,并包含其数量信息。一些文档包含描述水果或其供应商的字段。

#[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>>
}

以下部分中的示例查询由 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 文档

返回

检索数据