前言
文档查询再CRUD操作中算是比较多样化的一操作,前面增删改的操作的形式基本是固定的,而查询文档涵盖了多种场景,所以放在一篇里面就导致篇幅过长,干脆分成几篇。
查询文档的基本语法
上一篇其实有用到,一看就只知道~那就是find方法,如下
db.COLLECTION_NAME.find(query, projection)
query 就是查询条件,如果不传则返回集合中所有的文档。projection使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
如果要讲返回的数据格式更好阅读的话,就在find 后面加个pretty()方法。
db.COLLECTION_NAME.find(query, projection).pretty()
条件查询
结合不同的业务场景,find中的第一个参数也是比较多样的,其中包括条件操作符,AND操作符以及OR操作符。
条件操作符
我们直接来看下,一开始我还觉得这种表达式生涩难以记住,后来结合其英文含义就变得十分好记。
| 表达式 | MongoDB | 释义 |
|---|---|---|
| < | $lt | less than |
| $gt | greater than | |
| = | $eq | equal |
| <= | $lte | less than equal |
| >= | $gte | greater than equal |
| != | $ne | not equal |
以下作为例子,我会建立了一个集合,并插入一个关于学生的成绩表,篇幅原因,我们就拿其中一种条件来演示一下即可。
> db.createCollection("col")
{ "ok" : 1 }
> var scoreList = [
{name: "mark", score: 80},
{name: "Tom", score: 65},
{name: "yellowbird", score: 100}
]
> db.col.insertMany(scoreList)
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("611dd35313e48bd44324e7f8"),
ObjectId("611dd35313e48bd44324e7f9"),
ObjectId("611dd35313e48bd44324e7fa")
]
}
> db.col.find()
{ "_id" : ObjectId("611dd35313e48bd44324e7f8"), "name" : "mark", "score" : 80 }
{ "_id" : ObjectId("611dd35313e48bd44324e7f9"), "name" : "Tom", "score" : 65 }
{ "_id" : ObjectId("611dd35313e48bd44324e7fa"), "name" : "yellowbird", "score" : 100 }
然后我们试着从中检索出80分及以上的学生。
> db.col.find({score: {$gte: 80}})
{ "_id" : ObjectId("611dd35313e48bd44324e7f8"), "name" : "mark", "score" : 80 }
{ "_id" : ObjectId("611dd35313e48bd44324e7fa"), "name" : "yellowbird", "score" : 100 }
AND条件
find方法的第一个参数是支持多个键对值查询的。
现在重名的现象十分多,假设刚刚上表的那个班级又来了一个yellowbird同学,而且和另一个yellowbird同学一起又经历了一次考试,倒霉孩子yellowbird2号没有考及格,班主任要找他谈话(查询name为yellowbird且分数低于60分的学生)。
> db.col.insert({name: "yellowbird", score: "55"})
WriteResult({ "nInserted" : 1 })
> db.col.find({name:"yellowbird", score:{$lt:60}})
{ "_id" : ObjectId("611dd35313e48bd44324e7fa"), "name" : "yellowbird", "score" : 55 }
OR条件
这里我们可以查询不及格或者大于80分的信息
> db.col.find({$or: [{score: {$gt: 80}},{score: {$lt: 60}}]})
{ "_id" : ObjectId("611dd35313e48bd44324e7fa"), "name" : "yellowbird", "score" : 100 }
{ "_id" : ObjectId("611dff0e13e48bd44324e7fc"), "name" : "yellowbird", "score" : 55 }
limit和skip方法
看到这里我想到的一个业务场景就是我们常用的表格分页返回的数据。如果希望返回部分数据,我们可以使用limit 方法,传入一个数字作为查询的条数,比如一页3条数据,就传入3。
> db.col.find().limit(3)
{ "_id" : ObjectId("611dd35313e48bd44324e7f8"), "name" : "mark", "score" : 80 }
{ "_id" : ObjectId("611dd35313e48bd44324e7f9"), "name" : "Tom", "score" : 65 }
{ "_id" : ObjectId("611dd35313e48bd44324e7fa"), "name" : "yellowbird", "score" : 100 }
>
然后配合skip方法,就可以筛选出第二页的数据。
> db.col.find().limit(3).skip(3)
{ "_id" : ObjectId("611dff0e13e48bd44324e7fc"), "name" : "yellowbird", "score" : 55 }
排序
排序我们使用sort方法,传入需要排序的键值,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。如下:
> db.col.find().sort({score: 1})
{ "_id" : ObjectId("611dff0e13e48bd44324e7fc"), "name" : "yellowbird", "score" : 55 }
{ "_id" : ObjectId("611dd35313e48bd44324e7f9"), "name" : "Tom", "score" : 65 }
{ "_id" : ObjectId("611dd35313e48bd44324e7f8"), "name" : "mark", "score" : 80 }
{ "_id" : ObjectId("611dd35313e48bd44324e7fa"), "name" : "yellowbird", "score" : 100 }
>
基本的查询就现在这里结束了。