MongoDB的CURD基本操作(三)——查找

注:本文基于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更新操作上一样能使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值