一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
上一篇中了解了mongodb和mysql的异同,mongodb中database和collection的基础知识。今天来学习一下document文档的知识。这个应该是mongodb中的核心知识了,毕竟在日常开发中我们绝大部分都是在针对文档进行开发。
那么我们首先来学习下mongodb中是如何进行增删改查的。先回顾下之前的新增操作。
> db.product.insert({name:'菜刀',price:43.9})
WriteResult({ "nInserted" : 1 })
我们插入了一条文档,里面包含了name和price两种属性。查询结果可以看到目前collection中所包含的文档。
> db.product.find()
{ "_id" : ObjectId("62519ac1bd42defeee43f2af"), "name" : "玩 具 汽 车 ", "price" : 50.2 }
{ "_id" : ObjectId("62525be9313bc6eb0c50cd9e"), "name" : "菜 刀 ", "price" : 43.9 }
这里我们来说明两个点,第一当我们在新建一个文档时没有指定它的主键_id,那么mongodb会替我们自动创建一个id,我们也可以自己指定这个id,但是需要注意要保证它在collection中的唯一性。
> db.product.insertOne({_id:'001',name:'苹 果 ',price:2.9})
{ "acknowledged" : true, "insertedId" : "001" }
> db.product.find()
{ "_id" : ObjectId("62519ac1bd42defeee43f2af"), "name" : "玩 具 汽 车 ", "price" : 50.2 }
{ "_id" : ObjectId("62525be9313bc6eb0c50cd9e"), "name" : "菜 刀 ", "price" : 43.9 }
{ "_id" : "001", "name" : "苹 果 ", "price" : 2.9 }
可以发现会使用我们自己定义的id。
第二个是类比于mysql,一般mysql在建表之后,内部的字段就已经确定了,如果后续发生变动,就需要对所有的记录进行新增字段或删除字段。但是在mongodb中,
> db.product.insertOne({name:'电火锅',price:100,label:'网红'})
{
"acknowledged" : true,
"insertedId" : ObjectId("62525f17313bc6eb0c50cd9f")
}
> db.product.find()
{ "_id" : ObjectId("62519ac1bd42defeee43f2af"), "name" : "玩具汽车", "price" : 50.2 }
{ "_id" : ObjectId("62525be9313bc6eb0c50cd9e"), "name" : "菜刀", "price" : 43.9 }
{ "_id" : "001", "name" : "苹果", "price" : 2.9 }
{ "_id" : ObjectId("62525f17313bc6eb0c50cd9f"), "name" : "电火锅", "price" : 100, "label" : "网红" }
我在新增的文档中相比于之前的加了一个label的属性,但是添加之后之前旧的文档并没有受到影响,也就是说明mongodb可以自由灵活地新增文档的字段,而不会影响之前的文档。这一点和elasticsearch是相同的。
我们再来试下删除,一般我们在开发中都是删除匹配的记录,mongodb再操作api中通常都有针对one和many的方法。one只会对匹配到的第一条记录做操作。
> db.product.deleteOne({_id:'001'})
{ "acknowledged" : true, "deletedCount" : 1 }
> db.product.find()
{ "_id" : ObjectId("62519ac1bd42defeee43f2af"), "name" : "玩 具 汽 车 ", "price" : 50.2 }
{ "_id" : ObjectId("62525be9313bc6eb0c50cd9e"), "name" : "菜 刀 ", "price" : 43.9 }
{ "_id" : ObjectId("62525f17313bc6eb0c50cd9f"), "name" : "电 火 锅 ", "price" : 100, "label" : "网 红 " }
删除符合id是001的文档。有一条被匹配到了,所以这一条会被删除。
我们再来看一下update操作,这个我觉得是和MySQL差别比较大的了。比如再mysql中,我们需要更新的话会这么写
update product set price = 200 where name = '玩具汽车';
那么会把所有是玩具汽车的记录的价格都更新为200。我们在mongodb中尝试一下
> db.product.update({'name':'玩 具 汽 车 '},{'price':200})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.find()
{ "_id" : ObjectId("62519ac1bd42defeee43f2af"), "price" : 200 }
{ "_id" : ObjectId("62525be9313bc6eb0c50cd9e"), "name" : "菜 刀 ", "price" : 43.9 }
{ "_id" : ObjectId("62525f17313bc6eb0c50cd9f"), "name" : "电 火 锅 ", "price" : 100, "label" : "网 红 " }
我们发现被修改的记录中其它字段都丢失了,这是因为mongodb直接把原有的数据覆盖了,我们需要指定它的操作类型。例如
> db.product.update({'name':'菜刀'},{$set:{'price':200}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.product.find()
{ "_id" : ObjectId("62519ac1bd42defeee43f2af"), "price" : 200 }
{ "_id" : ObjectId("62525be9313bc6eb0c50cd9e"), "name" : "菜刀", "price" : 200 }
{ "_id" : ObjectId("62525f17313bc6eb0c50cd9f"), "name" : "电火锅", "price" : 100, "label" : "网红" }
$set运算符可以将字段更新为指定的值。
我们再来看下查询操作,之前我们已经看过了查询操作find()方法。这个是查询整个collection的,我们也可以指定查询条件
> db.product.find({name:'菜 刀 '})
{ "_id" : ObjectId("62525be9313bc6eb0c50cd9e"), "name" : "菜 刀 ", "price" : 200 }
我们可以只查询名称是菜刀的文档,过滤掉其它的文档。
在平时我们开发中不会将全部字段都返回给客户端,一方面是安全行另一方面是io性能,这种操作在sql中叫做投影。
> db.product.find({name:'菜 刀 '},{price: 1,_id: 0})
{ "price" : 200 }
可以看到只返回了price,这里的参数1代表返回,0代表不返回。 以上就是mongodb中对于文档的基本操作了。