在MongoDB中,条件查询是从集合中筛选数据的核心操作。通过指定不同的条件,我们可以精确地获取符合需求的文档。本文将从简单到复杂,用具体示例讲解MongoDB的条件查询方法,适合初学者快速上手。
一、准备示例数据¶
为了方便演示,我们假设有一个名为users的集合,包含以下文档(可理解为用户信息表):
{
"_id": 1,
"name": "Alice",
"age": 25,
"hobbies": ["reading", "hiking"],
"address": { "city": "Beijing", "country": "China" }
},
{
"_id": 2,
"name": "Bob",
"age": 30,
"hobbies": ["gaming", "coding"],
"address": { "city": "Shanghai", "country": "China" }
},
{
"_id": 3,
"name": "Charlie",
"age": 22,
"hobbies": ["music", "sports"],
"address": { "city": "Guangzhou", "country": "China" }
},
{
"_id": 4,
"name": "David",
"age": 35,
"hobbies": ["travel", "photography"],
"address": { "city": "Chengdu", "country": "China" }
}
二、基础条件查询(最简单的“等于”条件)¶
MongoDB中,条件查询通过find()方法实现,条件以“键值对”的形式写在查询文档中。最基础的条件是等于,即查询某个字段等于指定值的文档。
示例1:查询年龄为25的用户¶
db.users.find({ age: 25 })
- 解释:
{ age: 25 }是查询条件,表示“年龄字段等于25”。 - 结果:返回
_id为1的文档(Alice的信息)。
示例2:查询城市为“Shanghai”的用户¶
db.users.find({ "address.city": "Shanghai" })
- 解释:
address.city是嵌套字段的点表示法(address是父文档,city是子字段),表示查询地址中城市为“Shanghai”的文档。 - 结果:返回
_id为2的文档(Bob的信息)。
三、比较运算符(大于、小于、不等于等)¶
MongoDB支持多种比较运算符,用于更灵活的条件筛选,常见的有:
- $gt:大于(greater than)
- $lt:小于(less than)
- $gte:大于等于(greater than or equal)
- $lte:小于等于(less than or equal)
- $ne:不等于(not equal)
示例3:查询年龄大于25岁的用户¶
db.users.find({ age: { $gt: 25 } })
- 解释:
{ age: { $gt: 25 } }表示“年龄字段大于25”。 - 结果:返回
_id为2(Bob,30岁)、4(David,35岁)的文档。
示例4:查询年龄在22到30岁之间的用户(含22和30)¶
db.users.find({ age: { $gte: 22, $lte: 30 } })
- 解释:条件是一个对象,包含
$gte(大于等于)和$lte(小于等于),表示年龄范围在22到30之间。 - 结果:返回
_id为1(25岁)、2(30岁)、3(22岁)的文档。
示例5:查询姓名不等于“Bob”的用户¶
db.users.find({ name: { $ne: "Bob" } })
- 解释:
$ne表示“不等于”,即排除姓名为“Bob”的文档。 - 结果:返回
_id为1、3、4的文档。
四、逻辑运算符(AND、OR、NOT)¶
当需要组合多个条件时,MongoDB提供了逻辑运算符$and、$or、$not。
示例6:查询年龄大于25且城市为“China”的用户(AND条件)¶
db.users.find({
age: { $gt: 25 },
"address.country": "China"
})
- 解释:多个条件直接写在查询文档中,MongoDB默认是
AND关系,即同时满足“年龄>25”和“国家是China”。 - 结果:返回
_id为2(Bob,30岁,中国)、4(David,35岁,中国)的文档。
示例7:查询年龄25岁或城市为“Beijing”的用户(OR条件)¶
db.users.find({
$or: [
{ age: 25 },
{ "address.city": "Beijing" }
]
})
- 解释:
$or需要将条件放在数组中,每个元素是一个条件对象,满足任意一个条件即可。 - 结果:返回
_id为1(Alice,25岁)、1(Beijing)的文档。
示例8:查询年龄不大于30且爱好不含“gaming”的用户(NOT条件)¶
db.users.find({
age: { $not: { $gt: 30 } }, // 年龄≤30
hobbies: { $ne: "gaming" } // 爱好不等于gaming
})
- 解释:
$not用于否定条件,这里否定$gt:30(即年龄≤30),同时排除爱好含“gaming”的用户。 - 结果:返回
_id为1(Alice,25岁,爱好不含gaming)、3(Charlie,22岁,爱好不含gaming)的文档。
五、数组查询(处理数组字段)¶
如果文档包含数组类型(如hobbies),MongoDB支持数组相关的条件查询,常见场景包括:
- 数组包含某个元素
- 数组长度等于指定值
- 数组中元素满足特定条件
示例9:查询爱好包含“reading”的用户¶
db.users.find({ hobbies: "reading" })
- 解释:直接写数组元素作为条件,MongoDB默认会匹配数组中包含该元素的文档(相当于
$in操作)。 - 结果:返回
_id为1(Alice,爱好含reading)的文档。
示例10:查询爱好包含“reading”或“travel”的用户¶
db.users.find({ hobbies: { $in: ["reading", "travel"] } })
- 解释:
$in用于指定一个值列表,只要数组包含列表中的任意一个元素即可匹配。 - 结果:返回
_id为1(Alice,含reading)、4(David,含travel)的文档。
示例11:查询爱好数组长度为2的用户¶
db.users.find({ hobbies: { $size: 2 } })
- 解释:
$size用于指定数组长度,这里表示数组元素个数为2。 - 结果:返回
_id为1(Alice,2个爱好)、2(Bob,2个爱好)的文档。
六、字符串匹配查询(正则表达式)¶
使用$regex可以对字符串进行模糊匹配,支持正则表达式语法。
示例12:查询姓名以“A”开头的用户¶
db.users.find({ name: { $regex: /^A/ } })
- 解释:
/^A/是正则表达式,表示“以A开头”,$regex用于指定匹配规则。 - 结果:返回
_id为1(Alice)的文档。
示例13:查询姓名包含“li”且不区分大小写的用户¶
db.users.find({ name: { $regex: /li/i } })
- 解释:
/li/i中的i表示不区分大小写,li表示匹配包含“li”的字符串。 - 结果:若有姓名为“Alex”或“Li”的用户会被匹配,此处示例数据中无符合条件的用户。
七、总结¶
MongoDB条件查询通过组合不同的条件运算符和逻辑运算符,可以实现从简单到复杂的筛选需求。核心关键点:
1. 基础查询:直接通过字段名=值匹配(等于条件)。
2. 比较运算符:$gt/$lt等处理范围查询。
3. 逻辑运算符:$and(默认)、$or、$not组合多条件。
4. 数组查询:$in、$size等处理数组元素匹配。
5. 字符串匹配:$regex支持正则表达式模糊查询。
通过练习上述示例,你可以逐步掌握MongoDB条件查询的核心逻辑,应对大部分数据筛选场景。
练习题¶
尝试用以下条件查询,验证你的理解:
1. 查询年龄小于30岁且城市为“Guangzhou”的用户。
2. 查询爱好包含“coding”或“photography”的用户。
3. 查询姓名以“C”开头且年龄为偶数的用户。
(答案可在MongoDB客户端中执行对应查询语句验证)