🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 安装 - [mongo官网下载区](https://www.mongodb.com/download-center?jmp=nav#community) ## 设置环境变量 找到mongodb安装目录,一般是 C:\Program Files\MongoDB 2.6 Standard\bin 将它添加进系统环境变量中的path >计算机>属性>高级>环境变量>path ## 启动数据库服务器 -- port 默认为27017 -- logpath -- logappend -- dbpath -- directoryperdb ### 手动启动 先在你想要存储数据(数据库文档)的地方创建一个文件夹 比如我们想存放在e盘的mongo下 再输入命令 ``` //cmd中 mongod --dbpath E:\mdata --logpath E:\mlog --logappend --directoryperdb ``` 就会生成一个数据库 ![](https://box.kancloud.cn/a24d2e423341e81b3a366e31327ec77d_451x448.png) >[danger] 用以启动服务端的CMD不能关闭,一旦这个cmd关闭,数据库服务器就会自动关闭 ### 用服务器启动 添加服务 >[danger] **注意:** mlog是一个文件,mdata是一个文件夹(需提前创建) ``` //cmd中 mongod.exe --dbpath E:\mdata --logpath E:\mlog --logappend --directoryperdb --serviceName mongodb --install net start mongodb net stop mongodb ``` 添加`--directoryperdb`会将每个数据库单独作为一个文件夹存放 删除服务 ``` sc delete mongodb ``` ## 数据库服务器目录分布 - admin数据库 用来管理数据库,数据库有哪些用户,哪些权限,操作哪些集合,是否可读可写等 - local数据库 - Collections 集合文件夹 - startup_log 启动日志集合 ![](https://box.kancloud.cn/e6bde8ad45cd5e2c7be3897d0aa202d2_689x138.png) 一个集合有三种形式的视图 ... ## 连接数据库 命令窗体中输入 mongo --host=127.0.0.1 或者 mongo 按回车键 ``` mongo //一般直接敲回车即可 ``` 如果出现类似waiting for connections on port 27017就表示启动成功,已经在27017端口上监听了客户端的请求 ## mongdb基本概念 ![](http://7xjf2l.com1.z0.glb.clouddn.com/mongodbstructure.jpg) ![](http://7xjf2l.com1.z0.glb.clouddn.com/mongovue.png) - 数据库 MongoDB的单个实例可以容纳多个独立的数据库,比如一个学生管理系统就可以对应一个数据库实例 - 集合 数据库是由集合组成的,一个集合用来表示一个实体,如学生集合 - 文档 集合是由文档组成的,一个文档表示**一条记录**,比如一位同学张三就是一个文档 ## 数据库操作 ### 注意事项 mongdb中没有单独的创建数据的命令,只能通过`use`切换数据库(即使这个数据库不存在)。 当添加文档时,若一个数据库不存在,或则集合,又或则一个文档不存在,它会自动级联创建。 ### 帮助命令 ``` db.help(); ``` ### 显示数据库列表 ``` show dbs ``` >我们刚创建的数据库school如果不在列表内, 要显示它,我们需要向school数据库插入一些数据 ``` db.students.insert({name:'zfpx',age:1}); ``` ### 切换数据库 >即使数据库不存在也可以切换,但只有当我们往里插入一个文档的时候才会真正创建该文档。 ``` use database_name database_name代表数据库的名字 ``` ### 查看当前使用的数据库 ``` db 或 db.getName() ``` ### 删除数据库 ``` db.dropDatabase() ``` ### 关闭数据库 让数据库服务器关闭 ``` use admin; db.shutdownServer(); ``` ## 集合操作 ### 查看帮助 ``` db.students.help() //students是我们自己创的一个集合 ``` ### 查看数据库下的集合 ``` show collections ``` ### 创建集合 创建一个空集合 ``` db.createCollection(collection_Name) ``` 创建集合并插入一个文档 ``` db.collection_Name.insert(document) ``` ### 删除当前数据下的xx集合 ``` db.students.drop() drop the collection ,删除集合 ``` ## 文档操作 ### 默认行为 当我们创建一个文档时,mongdb会自动为这条文档添加一个`_id`属性,它是一个绝对唯一的标识(因为mongdb是一个分布式数据库) 之前我们使用MySQL等关系型数据库时,主键都是设置成自增的。但分布式环境下,这种方法就不可行了,会产生冲突,为此MongDB采用了一个称之为Objectid的类型来做主键。Objectid是一个12字节的BSON类型字符串。按照字节顺序,依次代表: - 4字节:UNIX时间戳 - 3字节:表示运行MongDB的机器 - 2字节:表示生成此_id的进程 - 3字节:由一个随机数开始的计数器生成的值 但我们也可以手动指定id ``` db.xxx.insert({_id:111,name:'ahhh'}); ``` ### insert ``` db.collection_name.insert(document) ``` >每当插入一条新文档的时候mongodb会自动为此文档生成一个_id属性,_id一定是唯一的,用来唯一标识一个文档 _id也可以直接指定,但如果数据库中此集合下已经有此_id的话插入会失败 ``` > db.students.insert({_id:1,name:'ahhh',age:1}); <<< WriteResult({ "nInserted" : 1 }) > db.students.insert({_id:1,name:'ahhh',age:1}); ``` #### 批量插入 ``` var db = connect('school'); var start = Date.now(); for(var i=0;i<1000;++i){ db.students.insert({name:'zfpx'+i,age:i}); } var cost = (Date.now() - start)/1000+'s'; print('cost:'+cost); ``` 推荐使用`insert([{},{}])`数组的形式。 ``` var db = connect('school'); var start = Date.now(); var stus = []; for(var i=0;i<1000;++i){ stus.push({name:'zfpx'+i,age:i}); } db.students.insert(stus); var cost = (Date.now() - start)/1000+'s'; print('cost:'+cost); ``` ### save ``` db.collection_name.save(document) ``` 其中document就是一个`{}`json >注:如果不指定 _id 字段 save() 方法类似于 insert() 方法。如果指定 _id 字段,则会更新该 _id 的数据。 ### update ``` db.collection.update( <query>, <updateObj>, { upsert: <boolean>, multi: <boolean> } ) ``` - query 查询条件,指定要更新符合哪些条件的文档 - update 更新后的对象或指定一些更新的操作符 - $set直接指定更新后的值 - $inc在原基础上累加 - upsert 可选,这个参数的意思是,如果不存在符合条件的记录时是否插入updateObj. 默认是false,不插入。 - multi 可选,mongodb 默认只更新找到的第一条记录,如果这个参数为true,就更新所有符合条件的记录。 --- #### 完全替换 默认情况下会将通过query查找到的第一条数据完全**替换**成updateObj 比如下面这个例子 ``` //此处示例省略了_id //原数据{"name":"ahhh","age":"1"} db.students.update({name:'ahhh'},{age:101}) <<<修改后 {"age":"101"} ``` #### 通过$set操作符更新文档(非替换) ``` db.students.update({name:'ahhh2'},{$set:{age:300}}); ``` 除此之外`$set`也能给文档添加一个字段 ``` db.students.update({name:'ahhh'},{$set:{add:1}}); ``` 默认是一次只查找一条添加,我们可以通过`multi`属性进行批量操作 ``` db.students.update({name:'ahhh'},{$set:{other:1}},{multi:true}); ``` 如果要更改的字段的值是一个数组,可以通过`.索引`来对数组中某一项进行更改 ``` //注意索引是从0开始的 db.students.update({name:'ahhh'},{$set:{hobby.0:'drinking'}}); ``` #### $unset删除字段 ``` db.students.update({name:'ahhh'},{$unset:{other:1}},{multi:true}); ``` #### 自增:$inc ``` db.students.update({name:'ahhh2'},{$inc:{age:2}}); //每次累加2 ``` #### upsert upsert 可选,这个参数的意思是,如果不存在符合条件的记录时是否插入updateObj. 默认是false,不插入 ``` db.students.update({name:'ahhh101'},{sex:'female'},{upsert:true}); <<< //会添加这面一条文档 {"_id":...,"sex":"female"} ``` 上面并不会自动插入name字段 如果需要,我们需要配合使用`$set` ``` db.students.update({name:'ahhh000'},{$set:{sex:'female'}},{upsert:true}); <<< //会添加这面一条文档 {"_id":...,"name":"ahhh000","sex":"female"} ``` ##### upsert和 save ``` db.students.save({name:'ahhh'}) db.students.update({name:'ahhh'},{$set:{sex:'female'}},{upsert:true}); ``` save会直接创建一条{name:'ahhh'},而update+upsert会先查询是否有一条存在name=ahhh的文档。 #### $push 以数组形式作为值添加到属性 ``` db.students.update({name:'ahhh'},{$push:{hooby:'smoking'}}); ``` 重复命令,会在同一条文档中重复添加 smoking(不会替换,而是追加) #### $ne not equal 不相等 只要hobby不是smoking,就会被替换成updateObj ``` db.students.update({hobby:{$ne:'smoking'}},{city:'beijing'}); ``` #### $addToSet 如果该属性下存在这个值就略过,如果没有就往这个属性的值数组中追加你设定的值。 ``` db.students.update({name:'ahhh'},{$addToSet:{hobby:'drinking'}); ``` >[danger] 注意如添加的不是`''`,而是`[]`,则会往数组里添加一个数组 ``` //错误的使用方式 db.students.update({name:'ahhh'},{$addToSet:{hobby:['read','play']}); ``` 应该使用`$each`展开数组 ``` //正确的使用方式 db.students.update({name:'ahhh'},{$addToSet:{hobby:$each:['read','play']}); ``` #### $pop 删除数组值中的某项 值为1是是删除最后一项,值为-1时是删除第一项 ``` db.students.update({name:'ahhh'},{$pop:{hobby:1}}); ``` #### var 与 print ``` var r = db.students. update(...) print(r); <<< writeresult ``` #### runCommand ``` //test.js var cmd = { findAndModify:'students' //要操作的集合 ,query:{name:'ahhh'} ,update:{$set:{age:100}} ,fields:{name:1} //指定要返回的文档的字段 1|true返回 0|false不返回,默认只有id是默认要返回的,其它都不是 //额外的,如果什么都不指定,表示全返回 ,sort:{age:1} //按age字段进行排序,1为正序,-1倒叙 ,new:true //返回修改后的文档,为false时是更行前的文档 } var db = connect('school'); //链接到school数据库 var result = db.runCommand(cmd); printjson(result); ``` 然后在命令行运行该脚本 ``` mongo test.js <<< { "lastErrorObject" : { "n" : 1, "updatedExisting" : true }, "value" : { "_id" : ObjectId("5add4f94195168b828292746"), "name" : "ahhh" }, "ok" : 1 } ``` 另外如果你已经在用客户端连接数据库服务器(已经通过mongo命令连接) ``` load('./test.js'); ``` ### count 显示当前集合的文档总数 ``` db.students.count(); ``` ### remove ``` db.collection.remove( <query>, { justOne: <boolean> } ) ``` - query :(可选)删除的文档的条件。 - justOne : (可选)如果设为 true 或 1,则只删除匹配到的多个文档中的第一个 默认会删除所有匹配上的文档 示例:因为使用了justOne参数,So即使匹配多条也只删除一条 ``` > db.students.remove({name:"ahhh"},{justOne:true}) WriteResult({ "nRemoved" : 1 }) ```