MongoDB查询文档的基本操作与示例
MongoDB查询文档的基本操作与示例
1. 简单查询
在MongoDB中,最简单的查询就是查找集合中的所有文档。使用find()
方法,不传递任何参数时,它会返回集合中的所有文档。例如,假设有一个名为students
的集合,存储了学生的信息,以下是查询所有学生信息的代码示例:
// 使用JavaScript示例,连接到MongoDB数据库
const { MongoClient } = require('mongodb');
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);
async function findAllStudents() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const allStudents = await studentsCollection.find({}).toArray();
console.log(allStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findAllStudents();
在上述代码中,我们使用Node.js的MongoDB驱动程序,连接到本地的MongoDB实例,选择school
数据库中的students
集合,通过find({})
方法获取所有文档,并使用toArray()
方法将游标转换为数组以便于查看。
2. 条件查询
2.1 等于条件查询
通常我们不会查询所有文档,而是根据特定条件进行筛选。要查询符合某个字段等于特定值的文档,可以在find()
方法的第一个参数中指定条件。例如,查询所有年龄为20岁的学生:
async function findStudentsByAge() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const studentsWithAge20 = await studentsCollection.find({ age: 20 }).toArray();
console.log(studentsWithAge20);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findStudentsByAge();
在这个例子中,{ age: 20 }
就是查询条件,表示只返回age
字段值为20的文档。
2.2 比较条件查询
MongoDB提供了丰富的比较操作符,如大于($gt
)、小于($lt
)、大于等于($gte
)、小于等于($lte
)等。例如,查询所有年龄大于20岁的学生:
async function findStudentsOlderThan20() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const olderStudents = await studentsCollection.find({ age: { $gt: 20 } }).toArray();
console.log(olderStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findStudentsOlderThan20();
这里使用了$gt
操作符,{ age: { $gt: 20 } }
表示age
字段值大于20的文档。
2.3 不等于条件查询
使用$ne
操作符可以查询字段值不等于某个值的文档。例如,查询所有年龄不等于20岁的学生:
async function findStudentsNot20() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const not20Students = await studentsCollection.find({ age: { $ne: 20 } }).toArray();
console.log(not20Students);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findStudentsNot20();
3. 逻辑查询
3.1 与($and)查询
$and
操作符用于连接多个条件,只有当所有条件都满足时,文档才会被返回。假设要查询年龄大于20岁且成绩大于80分的学生:
async function findQualifiedStudents() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const qualifiedStudents = await studentsCollection.find({
$and: [
{ age: { $gt: 20 } },
{ score: { $gt: 80 } }
]
}).toArray();
console.log(qualifiedStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findQualifiedStudents();
在上述代码中,$and
数组中包含两个条件,只有同时满足这两个条件的文档才会被返回。
3.2 或($or)查询
$or
操作符只要其中一个条件满足,文档就会被返回。例如,查询年龄小于18岁或者成绩小于60分的学生:
async function findProblemStudents() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const problemStudents = await studentsCollection.find({
$or: [
{ age: { $lt: 18 } },
{ score: { $lt: 60 } }
]
}).toArray();
console.log(problemStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findProblemStudents();
3.3 与或混合查询
也可以进行与或混合的复杂查询。例如,查询年龄大于20岁且(成绩大于80分或者性别为男)的学生:
async function findSpecialStudents() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const specialStudents = await studentsCollection.find({
age: { $gt: 20 },
$or: [
{ score: { $gt: 80 } },
{ gender: '男' }
]
}).toArray();
console.log(specialStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findSpecialStudents();
4. 范围查询
$in
操作符用于查询字段值在指定数组范围内的文档,$nin
则相反,查询字段值不在指定数组范围内的文档。
4.1 $in查询
例如,查询年龄为18、20、22岁的学生:
async function findStudentsByAges() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const selectedStudents = await studentsCollection.find({ age: { $in: [18, 20, 22] } }).toArray();
console.log(selectedStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findStudentsByAges();
4.2 $nin查询
查询年龄不在18、20、22岁范围内的学生:
async function findStudentsNotInAges() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const otherStudents = await studentsCollection.find({ age: { $nin: [18, 20, 22] } }).toArray();
console.log(otherStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findStudentsNotInAges();
5. 正则表达式查询
MongoDB支持使用正则表达式进行字符串匹配查询。例如,查询名字以“张”开头的学生:
async function findZhangStudents() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const zhangStudents = await studentsCollection.find({ name: /^张/ }).toArray();
console.log(zhangStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findZhangStudents();
在上述代码中,/^张/
是一个正则表达式,表示以“张”开头的字符串。
6. 查询字段投影
在查询时,我们可以指定返回的字段,而不是返回整个文档,这就是字段投影。例如,只查询学生的姓名和年龄,不返回其他字段:
async function findNameAndAge() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const nameAndAge = await studentsCollection.find({}, { name: 1, age: 1, _id: 0 }).toArray();
console.log(nameAndAge);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findNameAndAge();
在find()
方法的第二个参数中,name: 1
和age: 1
表示返回这两个字段,_id: 0
表示不返回_id
字段。默认情况下,_id
字段会被返回,如果不想返回需要显式设置为0。
7. 限制结果集
7.1 limit方法
limit()
方法用于限制返回的文档数量。例如,只查询前5个学生:
async function findFirst5Students() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const first5Students = await studentsCollection.find().limit(5).toArray();
console.log(first5Students);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findFirst5Students();
7.2 skip方法
skip()
方法用于跳过指定数量的文档。例如,跳过前3个学生,查询后面的学生:
async function skipFirst3Students() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const skippedStudents = await studentsCollection.find().skip(3).toArray();
console.log(skippedStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
skipFirst3Students();
也可以同时使用limit()
和skip()
方法进行分页查询。例如,每页显示10条数据,查询第2页的数据:
async function paginateStudents() {
const page = 2;
const pageSize = 10;
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const paginatedStudents = await studentsCollection.find()
.skip((page - 1) * pageSize)
.limit(pageSize)
.toArray();
console.log(paginatedStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
paginateStudents();
8. 排序查询
使用sort()
方法可以对查询结果进行排序。sort()
方法接受一个文档作为参数,指定按哪些字段排序以及排序的方向(1表示升序,-1表示降序)。例如,按年龄升序查询学生:
async function sortStudentsByAgeAsc() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const sortedStudents = await studentsCollection.find().sort({ age: 1 }).toArray();
console.log(sortedStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
sortStudentsByAgeAsc();
如果要按年龄降序,成绩升序排序,可以这样写:
async function complexSortStudents() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const sortedStudents = await studentsCollection.find().sort({ age: -1, score: 1 }).toArray();
console.log(sortedStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
complexSortStudents();
9. 嵌套文档查询
如果文档中包含嵌套结构,查询方式会有所不同。假设students
集合中的文档结构如下:
{
"name": "张三",
"age": 20,
"address": {
"city": "北京",
"district": "朝阳区"
}
}
要查询地址在朝阳区的学生,可以这样写:
async function findStudentsInChaoyang() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const chaoyangStudents = await studentsCollection.find({ "address.district": "朝阳区" }).toArray();
console.log(chaoyangStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findStudentsInChaoyang();
这里使用点号(.
)来指定嵌套字段的路径。
10. 数组查询
10.1 匹配数组元素
如果文档中包含数组字段,例如学生的爱好数组:
{
"name": "李四",
"age": 22,
"hobbies": ["篮球", "音乐", "阅读"]
}
要查询爱好中有“篮球”的学生,可以这样写:
async function findBasketballLovers() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const basketballLovers = await studentsCollection.find({ hobbies: "篮球" }).toArray();
console.log(basketballLovers);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findBasketballLovers();
10.2 数组大小查询
使用$size
操作符可以查询数组大小符合条件的文档。例如,查询有3个爱好的学生:
async function findStudentsWith3Hobbies() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const studentsWith3Hobbies = await studentsCollection.find({ hobbies: { $size: 3 } }).toArray();
console.log(studentsWith3Hobbies);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findStudentsWith3Hobbies();
10.3 数组元素全部匹配
有时需要查询数组中所有元素都满足某个条件的文档。例如,查询爱好中同时包含“篮球”和“阅读”的学生,需要使用$all
操作符:
async function findAllMatchStudents() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const allMatchStudents = await studentsCollection.find({ hobbies: { $all: ["篮球", "阅读"] } }).toArray();
console.log(allMatchStudents);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
findAllMatchStudents();
11. 聚合查询
聚合查询可以对文档进行复杂的数据分析和处理。例如,计算学生的平均年龄:
async function calculateAverageAge() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const averageAge = await studentsCollection.aggregate([
{
$group: {
_id: null,
averageAge: { $avg: "$age" }
}
}
]).toArray();
console.log(averageAge);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
calculateAverageAge();
在上述代码中,$group
操作符用于分组,_id: null
表示不进行分组,$avg
是聚合操作符,用于计算平均值。
又如,按性别统计学生人数:
async function countStudentsByGender() {
try {
await client.connect();
const db = client.db('school');
const studentsCollection = db.collection('students');
const countByGender = await studentsCollection.aggregate([
{
$group: {
_id: "$gender",
count: { $sum: 1 }
}
}
]).toArray();
console.log(countByGender);
} catch (e) {
console.error(e);
} finally {
await client.close();
}
}
countStudentsByGender();
这里_id: "$gender"
表示按gender
字段进行分组,$sum: 1
用于统计每组的文档数量。
通过以上这些基本操作和示例,你可以对MongoDB的查询功能有一个较为全面的了解,能够根据不同的业务需求进行灵活的文档查询。在实际应用中,还需要根据数据量、性能等因素进一步优化查询语句。