注:本文基于MongoDB 4.2.6编写
1、查找
- 查找集合所有文档
> db.bb.find()
{ "_id" : ObjectId("5ec29c1e6b02bc57526eb598"), "hello" : "ball", "animals" : { "pig" : 80, "cow" : 200, "dog" : 50 }, "may" : "May", "happy" : "ending" }
{ "_id" : ObjectId("5ec5384c6d59a15615f7df04"), "hello" : "ball", "name" : "jan", "happy" : "ending" }
为了便于阅读,我们可以对结果进行优化显示,
> db.bb.find().pretty()
{
"_id" : ObjectId("5ec29c1e6b02bc57526eb598"),
"hello" : "ball",
"animals" : {
"pig" : 80,
"cow" : 200,
"dog" : 50
},
"may" : "May",
"happy" : "ending"
}
{
"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
"hello" : "ball",
"name" : "jan",
"happy" : "ending"
}
- 查找特定文档
> db.bb.find({"name": "jan"}).pretty()
{
"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
"hello" : "ball",
"name" : "jan",
"happy" : "ending"
}
- 查找并返回特定字段
通过使用find的第二个参数来控制返回哪些字段,
> db.bb.find({"name": "jan"}, {"hello": 1, "name": 1}).pretty()
{
"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
"hello" : "ball",
"name" : "jan"
}
有一点需要注意的是,不能同时制定哪些返回和哪些不返回,否则会报错,
> db.bb.find({"name": "jan"}, {"hello": 0, "_id": 1}).pretty()
Error: error: {
"ok" : 0,
"errmsg" : "Projection cannot have a mix of inclusion and exclusion.",
"code" : 2,
"codeName" : "BadValue"
}
- 条件查询
> db.bb.find().pretty()
{
"_id" : ObjectId("5ec684c3b97b4da914bd5e67"),
"name" : "mike",
"score" : 90
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e68"),
"name" : "john",
"score" : 90
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e69"),
"name" : "lucy",
"score" : 100
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96
}
> db.bb.find({score: {$gt: 90, $lt: 100}}).pretty()
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96
}
> db.bb.find({score: {$in:[96, 100]}}).pretty()
{
"_id" : ObjectId("5ec684fab97b4da914bd5e69"),
"name" : "lucy",
"score" : 100
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96
}
> db.bb.find({$or: [{name: "jack"}, {score: 96}]}).pretty()
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96
}
- 正则表达式
> db.bb.find({name: /ja.*/}).pretty()
{
"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
"hello" : "ball",
"name" : "jan",
"happy" : "ending"
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96
}
- 数组查询
对于匹配一个元素,直接键值对查询即可,如果需要同时匹配多个元素,要配合$all使用,
> db.bb.find({sport: "run"}).pretty()
{
"_id" : ObjectId("5ec697c0b97b4da914bd5e6b"),
"sport" : [
"run",
"swin",
"jump",
"tennis"
]
}
> db.bb.find({sport: {$all: ["run", "swin"]}}).pretty()
{
"_id" : ObjectId("5ec697c0b97b4da914bd5e6b"),
"sport" : [
"run",
"swin",
"jump",
"tennis"
]
}
但是如果数组中有多个元素,如下,记录了三人两次考试成绩,
> db.bb.find().pretty()
{
"_id" : ObjectId("5ed6554230571733ccb3d67b"),
"players" : [
{
"name" : "aa",
"score" : 98
},
{
"name" : "dan",
"score" : 95
},
{
"name" : "du",
"score" : 100
}
]
}
{
"_id" : ObjectId("5ed6579b30571733ccb3d67c"),
"players" : [
{
"name" : "aa",
"score" : 99
},
{
"name" : "dan",
"score" : 98
},
{
"name" : "du",
"score" : 90
}
]
}
如果需要找出du同学考试成绩大于95分的记录,
> db.bb.find({players: {name: "du", score: {$gt: 95}}}).pretty()
>
这种方式是无法查找出记录的,因为对于内嵌文档需要整个文档匹配,因此这是不可行的,
> db.bb.find({"players.name": "du", "players.score": {$gt: 95}}).pretty()
{
"_id" : ObjectId("5ed6554230571733ccb3d67b"),
"players" : [
{
"name" : "aa",
"score" : 98
},
{
"name" : "dan",
"score" : 95
},
{
"name" : "du",
"score" : 100
}
]
}
{
"_id" : ObjectId("5ed6579b30571733ccb3d67c"),
"players" : [
{
"name" : "aa",
"score" : 99
},
{
"name" : "dan",
"score" : 98
},
{
"name" : "du",
"score" : 90
}
]
}
>
而直接使用内嵌文档字段查询,也是有问题的,因为这相当于在整个内嵌文档中进行匹配,由于两个文档中都有du同学,同时都有同学的分数大于95,因此返回了两个文档。
这时候就要需要$elemMatch,它可以匹配内嵌文档中单个文档,也就是能将查询条件分组,以组作为查询条件就不会出现刚才的情况,
> db.bb.find({players: {$elemMatch: {name: "du", score: {$gt: 95}}}}).pretty()
{
"_id" : ObjectId("5ed6554230571733ccb3d67b"),
"players" : [
{
"name" : "aa",
"score" : 98
},
{
"name" : "dan",
"score" : 95
},
{
"name" : "du",
"score" : 100
}
]
}
- $slice切片
主要用于返回符合条件的数组元素的子集,比如前面10个元素,最后10个,中间2-8个等条件,
> db.bb.find().pretty()
{
"_id" : ObjectId("5ec697c0b97b4da914bd5e6b"),
"sport" : [
"run",
"swin",
"jump",
"tennis"
],
"name" : "geek"
}
> db.bb.find({name: "geek"}, {sport: {$slice: -1}}).pretty()
{
"_id" : ObjectId("5ec697c0b97b4da914bd5e6b"),
"sport" : [
"tennis"
],
"name" : "geek"
}
> db.bb.find({name: "geek"}, {sport: {$slice: [2,3]}}).pretty()
{
"_id" : ObjectId("5ec697c0b97b4da914bd5e6b"),
"sport" : [
"jump",
"tennis"
],
"name" : "geek"
}
- 查询结果进一步操作,limit、skip、sort
limit用于限制返回结果数量,skip用于指定返回结果跳过的数量,sort用于对返回结果的排序
> db.bb.find({name: /^j.*/}).pretty()
{
"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
"hello" : "ball",
"name" : "jan",
"happy" : "ending",
"email" : "com"
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e68"),
"name" : "john",
"score" : 90
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96,
"email" : "com"
}
> db.bb.find({name: /^j.*/}).limit(2).pretty()
{
"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
"hello" : "ball",
"name" : "jan",
"happy" : "ending",
"email" : "com"
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e68"),
"name" : "john",
"score" : 90
}
> db.bb.find({name: /^j.*/}).skip(2).pretty()
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96,
"email" : "com"
}
> db.bb.find({name: /^j.*/}).sort({name: 1}).pretty()
{
"_id" : ObjectId("5ec684fab97b4da914bd5e6a"),
"name" : "jack",
"score" : 96,
"email" : "com"
}
{
"_id" : ObjectId("5ec5384c6d59a15615f7df04"),
"hello" : "ball",
"name" : "jan",
"happy" : "ending",
"email" : "com"
}
{
"_id" : ObjectId("5ec684fab97b4da914bd5e68"),
"name" : "john",
"score" : 90
}
其中,sort参数中指定对某个字段进行升序(1)或者降序(-1)排序,
基本上find上能使用的查找语法在update更新操作上一样能使用。