mogodb的使用语句(命令)大全
官网学习网址:https://docs.mongodb.com/
mongo库表操作语句实际操作过程
1: mongo入门命令 1.1: show dbs 查看当前的数据库 1.2 use databaseName 选库 1.2 show tables/collections 查看当前库下的collection 1.3 如何创建库? Mongodb的库是隐式创建,你可以use 一个不存在的库 然后在该库下创建collection,即可创建库 1.4 db.createCollection(‘collectionName’) 创建collection 1.5 collection允许隐式创建 Db.collectionName.insert(document); 1.6 db.collectionName.drop() , 删除collection 1.7 db.dropDatabase(); 删除database
> use shop; #切换到不存在的库 switched to db shop > show collections; #没有集合 > db.createCollection('user'); #创建user集合 { "ok" : 1 } > show dbs; #查看数据库,已经生成数据库shop。切换到不存在的库中创建集合,那么库就会保存下来,如果不做任何操作,库就没有保存下来的 local 0.000GB shop 0.000GB > show collections; #查看集合,发现刚刚创建的user集合。有些版本能查到多了一个system.index索引文件。集合就相当于表,集合中可以放各式各样的文档,每个文档都可以是不同的 user > > db.user.insert({name:mcw,age:18}); #字符串得要加引号才行 2022-03-03T13:12:52.914+0800 E QUERY [thread1] ReferenceError: mcw is not defined : @(shell):1:17 > db.user.insert({name:'mcw',age:18}); #在user集合下创建一个文档 WriteResult({ "nInserted" : 1 }) > db.user.find(); #查找user集合下的文档。发现刚刚创建的文档,不过多添加了一个"_id"的字段。id当主键用的 { "_id" : ObjectId("62204e8caec42b1cbc12a09c"), "name" : "mcw", "age" : 18 } > db.user.insert({_id:2,name:'xiaoma',age:15}) #我们还可以给文档指定id,不使用随机生成的。 WriteResult({ "nInserted" : 1 }) > db.user.find(); #查看文档,发现刚刚生成的,并且id是我们指定的 { "_id" : ObjectId("62204e8caec42b1cbc12a09c"), "name" : "mcw", "age" : 18 } { "_id" : 2, "name" : "xiaoma", "age" : 15 } > db.user.insert({_id:3,name:'xiaoguo',hobby:['basketball','football'],intro:{'title':'My intro',content:'from china'}}) WriteResult({ "nInserted" : 1 }) #我们还可以给字段下添加列表,字典等多层数据结构,想写多深就写多深 > db.user.find(); { "_id" : ObjectId("62204e8caec42b1cbc12a09c"), "name" : "mcw", "age" : 18 } { "_id" : 2, "name" : "xiaoma", "age" : 15 } { "_id" : 3, "name" : "xiaoguo", "hobby" : [ "basketball", "football" ], "intro" : { "title" : "My intro", "content" : "from china" } } > > db.goods.insert({id:1,name:'vivo',price:29}); WriteResult({ "nInserted" : 1 }) #创建一个商品的集合,不需要提前创建好集合,直接插入不存在的集合数据就创建好了 > show collections; goods user > db.goods.find(); # { "_id" : ObjectId("62207bfeaec42b1cbc12a09d"), "id" : 1, "name" : "vivo", "price" : 29 } > > show collections; #删除前查看集合存在 goods user > db.user.drop(); # 删除集合user true > show collections; #查看已经被删除 goods > > db.help(); #查看帮助信息 DB methods: db.adminCommand(nameOrDocument) - switches to 'admin' db, and runs command [ just calls db.runCommand(...) ] db.auth(username, password) db.cloneDatabase(fromhost) db.commandHelp(name) returns the help for the command db.copyDatabase(fromdb, todb, fromhost) db.createCollection(name, { size : ..., capped : ..., max : ... } ) db.createUser(userDocument) db.currentOp() displays currently executing operations in the db db.dropDatabase() db.eval() - deprecated db.fsyncLock() flush data to disk and lock server for backups db.fsyncUnlock() unlocks server following a db.fsyncLock() db.getCollection(cname) same as db['cname'] or db.cname db.getCollectionInfos([filter]) - returns a list that contains the names and options of the db's collections db.getCollectionNames() db.getLastError() - just returns the err msg string db.getLastErrorObj() - return full status object db.getLogComponents() db.getMongo() get the server connection object db.getMongo().setSlaveOk() allow queries on a replication slave server db.getName() db.getPrevError() db.getProfilingLevel() - deprecated db.getProfilingStatus() - returns if profiling is on and slow threshold db.getReplicationInfo() db.getSiblingDB(name) get the db at the same server as this one db.getWriteConcern() - returns the write concern used for any operations on this db, inherited from server object if set db.hostInfo() get details about the server's host db.isMaster() check replica primary status db.killOp(opid) kills the current operation in the db db.listCommands() lists all the db commands db.loadServerScripts() loads all the scripts in db.system.js db.logout() db.printCollectionStats() db.printReplicationInfo() db.printShardingStatus() db.printSlaveReplicationInfo() db.dropUser(username) db.repairDatabase() db.resetError() db.runCommand(cmdObj) run a database command. if cmdObj is a string, turns it into { cmdObj : 1 } db.serverStatus() db.setLogLevel(level,<component>) db.setProfilingLevel(level,<slowms>) 0=off 1=slow 2=all db.setWriteConcern( <write concern doc> ) - sets the write concern for writes to the db db.unsetWriteConcern( <write concern doc> ) - unsets the write concern for writes to the db db.setVerboseShell(flag) display extra information in shell output db.shutdownServer() db.stats() db.version() current version of the server > > show dbs; #删除db前查看 local 0.000GB shop 0.000GB > db.dropDatabase(); #当前是在shop下,删除db shop,如果不确定当前db,最好是查看清楚了再删除 { "dropped" : "shop", "ok" : 1 } > show dbs; #查询删除结果,shop已经被删除 local 0.000GB >
mongodb的crud操作过程详解
基本操作增删改查 增: insert 介绍: mongodb存储的是文档,. 文档是json格式的对象. 语法: db.collectionName.isnert(document); 1: 增加单篇文档 Db.collectionName.insert({title:’nice day’}); 2: 增加单个文档,并指定_id Db.collectionName.insert({_id:8,age:78,name:’lisi’}); 3.增加多个文档 db.collectionName.insert( [ {time:'friday',study:'mongodb'}, {_id:9,gender:'male',name:'QQ'} ] ) 删:remove 语法: db.collection.remove(查询表达式, 选项); 选项是指 {justOne:true/false},是否只删一行, 默认为false 注意 1: 查询表达式依然是个json对象 2: 查询表达式匹配的行,将被删掉. 3: 如果不写查询表达式,collections中的所有文档将被删掉. 例1: db.stu.remove({sn:’001’}); 删除stu表中 sn属性值为’001’的文档 例2: db.stu.remove({gender:’m’,true}); 删除stu表中gender属性为m的文档,只删除1行. 改 update操作 改谁? --- 查询表达式 改成什么样? -- 新值 或 赋值表达式 操作选项 ----- 可选参数 语法: db.collection.update(查询表达式,新值,选项); 例: db.news.update({name:'QQ'},{name:'MSN'}); 是指选中news表中,name值为QQ的文档,并把其文档值改为{name:’MSN’}, 结果: 文档中的其他列也不见了,改后只有_id和name列了. 即--新文档直接替换了旧文档,而不是修改 如果是想修改文档的某列,可以用$set关键字 db.collectionName.update(query,{$set:{name:’QQ’}}) 修改时的赋值表达式 $set 修改某列的值 $unset 删除某个列 $rename 重命名某个列 $inc 增长某个列 $setOnInsert 当upsert为true时,并且发生了insert操作时,可以补充的字段. Option的作用: {upsert:true/false,multi:true/false} Upsert---是指没有匹配的行,则直接插入该行.(和mysql中的replace一样) 例:db.stu.update({name:'wuyong'},{$set:{name:'junshiwuyong'}},{upsert:true}); 如果有name=’wuyong’的文档,将被修改 如果没有,将添加此新文档 例: db.news.update({_id:99},{x:123,y:234},{upsert:true}); 没有_id=99的文档被修改,因此直接插入该文档 multi: 是指修改多行(即使查询表达式命中多行,默认也只改1行,如果想改多行,可以用此选项) 例: db.news.update({age:21},{$set:{age:22}},{multi:true}); 则把news中所有age=21的文档,都修改 查: find, findOne 语法: db.collection.find(查询表达式,查询的列); Db.collections.find(表达式,{列1:1,列2:1}); 例1:db.stu.find() 查询所有文档 所有内容 例2: db.stu.find({},{gendre:1}) 查询所有文档,的gender属性 (_id属性默认总是查出来) 例3: db.stu.find({},{gender:1, _id:0}) 查询所有文档的gender属性,且不查询_id属性 例3: db.stu.find({gender:’male’},{name:1,_id:0}); 查询所有gender属性值为male的文档中的name属性
操作的对象是json对象
增:
> show dbs; local 0.000GB > use test switched to db test > show dbs; local 0.000GB > db.stu.insert({sn:'001',name:'mcw'}); #增加一个集合,集合里有个学生信息 WriteResult({ "nInserted" : 1 }) > db.stu.find(); { "_id" : ObjectId("62207fa0aec42b1cbc12a09e"), "sn" : "001", "name" : "mcw" } > show dbs; local 0.000GB test 0.000GB > > db.stu.insert({_id:2,sn:'002',name:'mcw2'}); #增加一个学生文档,指定自动生成的id WriteResult({ "nInserted" : 1 }) > db.stu.find(); { "_id" : ObjectId("62207fa0aec42b1cbc12a09e"), "sn" : "001", "name" : "mcw" } { "_id" : 2, "sn" : "002", "name" : "mcw2" } > json是一个对象,js里有数组,我们可以把多个对象放到一个数组里。批量创建多个文档 > db.stu.insert([{_id:3,sn:'003',name:'zhangfei'},{_id:4,sn:'004',name:'guanyu'},{_id:5,sn:'005',name:'liubei'}]); BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], #一次创建多个文档 "nInserted" : 3, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) > db.stu.find(); { "_id" : ObjectId("62207fa0aec42b1cbc12a09e"), "sn" : "001", "name" : "mcw" } { "_id" : 2, "sn" : "002", "name" : "mcw2" } { "_id" : 3, "sn" : "003", "name" : "zhangfei" } { "_id" : 4, "sn" : "004", "name" : "guanyu" } { "_id" : 5, "sn" : "005", "name" : "liubei" } > 可以深层插入 > db.stu.insert({name:{xing:'xiao',ming:'ma',jineng:['war','read']}}); WriteResult({ "nInserted" : 1 }) > db.stu.find(); { "_id" : ObjectId("62207fa0aec42b1cbc12a09e"), "sn" : "001", "name" : "mcw" } { "_id" : 2, "sn" : "002", "name" : "mcw2" } { "_id" : 3, "sn" : "003", "name" : "zhangfei" } { "_id" : 4, "sn" : "004", "name" : "guanyu" } { "_id" : 5, "sn" : "005", "name" : "liubei" } { "_id" : ObjectId("622082bcaec42b1cbc12a09f"), "name" : { "xing" : "xiao", "ming" : "ma", "jineng" : [ "war", "read" ] } } > 删除: 指定哪个属性是哪个值的文档删除掉 > db.stu.remove({sn:'001'}); #这是条件表达式,能查到多少行就删除多少行 WriteResult({ "nRemoved" : 1 }) > db.stu.find(); { "_id" : 2, "sn" : "002", "name" : "mcw2" } { "_id" : 3, "sn" : "003", "name" : "zhangfei" } { "_id" : 4, "sn" : "004", "name" : "guanyu" } { "_id" : 5, "sn" : "005", "name" : "liubei" } { "_id" : ObjectId("622082bcaec42b1cbc12a09f"), "name" : { "xing" : "xiao", "ming" : "ma", "jineng" : [ "war", "read" ] } } > 删除集合中所有文档 > db.stu.find(); { "_id" : 2, "sn" : "002", "name" : "mcw2" } { "_id" : 3, "sn" : "003", "name" : "zhangfei" } { "_id" : 4, "sn" : "004", "name" : "guanyu" } { "_id" : 5, "sn" : "005", "name" : "liubei" } { "_id" : ObjectId("622082bcaec42b1cbc12a09f"), "name" : { "xing" : "xiao", "ming" : "ma", "jineng" : [ "war", "read" ] } } > db.stu.remove({}); WriteResult({ "nRemoved" : 5 }) > db.stu.find(); > 指定查询符合字段条件的文档 > db.stu.find({sn:'002'}); { "_id" : 2, "sn" : "002", "name" : "mcw2" } > 删:remove 语法: db.collection.remove(查询表达式, 选项); 选项是指 {justOne:true/false},是否只删一行, 默认为false 注意 1: 查询表达式依然是个json对象 2: 查询表达式匹配的行,将被删掉. 3: 如果不写查询表达式,collections中的所有文档将被删掉. 现在插入四条数据 > db.stu.insert([{name:'mcw1',gender:'m'},{name:'mcw2',gender:'m'},{name:'mcw3',gender:'w'},{name:'mcw4',gender:'m'}]) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 4, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) > db.stu.find(); { "_id" : ObjectId("6220a087aec42b1cbc12a0a0"), "name" : "mcw1", "gender" : "m" } { "_id" : ObjectId("6220a087aec42b1cbc12a0a1"), "name" : "mcw2", "gender" : "m" } { "_id" : ObjectId("6220a087aec42b1cbc12a0a2"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a087aec42b1cbc12a0a3"), "name" : "mcw4", "gender" : "m" } > > #删除满足花括号内指定条件的数据,如果没指定条件就是删除所有 > db.stu.remove({gender:"m"}); WriteResult({ "nRemoved" : 3 }) > db.stu.find(); { "_id" : ObjectId("6220a087aec42b1cbc12a0a2"), "name" : "mcw3", "gender" : "w" } > > 将数据重新加成如下。然加个true删除,这样只删除满足条件的一个值,默认是false,删除满足条件的所有 > db.stu.find(); { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a4"), "name" : "mcw1", "gender" : "m" } { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a5"), "name" : "mcw2", "gender" : "m" } { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a6"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a7"), "name" : "mcw4", "gender" : "m" } > db.stu.remove({gender:"m"},true); WriteResult({ "nRemoved" : 1 }) > db.stu.find(); { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a5"), "name" : "mcw2", "gender" : "m" } { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a6"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a7"), "name" : "mcw4", "gender" : "m" } > > 将名字是mcw2的改成mm2,因为只写了修改字段属性,其它属性没添加,那么修改后只有这个修改了的name属性,并且是修改过的值。这显然不是我们需要的结果。我们还需要gender属性 > 直接将新文档替换旧文档 > db.stu.update({name:'mcw2'},{name:'mm2'}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.stu.find(); { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a5"), "name" : "mm2" } { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a6"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a2ddaec42b1cbc12a0a7"), "name" : "mcw4", "gender" : "m" } > > > 如下我们将文档恢复。然后需要将mcw2改为mm2,保持其它属性不变。正确的做法是将修改后的字段属性放到{$set:值}值的位置,如下操作 > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mcw2", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "m" } > > db.stu.update({name:'mcw2'},{$set:{name:'mm2'}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "m" } > db.stu.insert({ name:'wukong', jingu: true, sex:'m', age:500 }) 修改时的赋值表达式 $set 修改某列的值# 修改字段对应的值) $unset 删除某个列 #删除指定字段,需要将字段设置值为1 $rename 重命名某个列 #给字段重命名 $inc 增长某个列 #给字段值增加指定数值 $setOnInsert 当upsert为true时,并且发生了insert操作时,可以补充的字段. 首先需要将wukon改为douzhanshengfo,把jingu去掉,把sex字段改掉成gender,年龄修改为增加16年 db.stu.update({name:'wukong'},{ $set:{name:'douzhanshengfo'}, $unset:{jingu:1}, $rename:{sex:'gender'}, $inc:{age:1} }) > > #如下可以看到,名字值被修改了,jingu字段删除了,字段名sex被重命名了,字段年龄值再原基础上增加1了 > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "m" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "wukong", "jingu" : true, "sex" : "m", "age" : 500 } > db.stu.update({name:'wukong'},{ ... $set:{name:'douzhanshengfo'}, ... $unset:{jingu:1}, ... $rename:{sex:'gender'}, ... $inc:{age:1} ... }) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "m" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "m" } > 修改字段值,默认只修改满足条件的一个,貌似是最早创建的那个 > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "m" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "m" } > db.stu.update({gender:'m'},{$set:{gender:'male'}}); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "m" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "m" } > 如果需要修改满足条件的所有的字段值,那么需要添加{multi:true}的属性,如下都被修改了。也可以是{multi:1} > > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "m" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "m" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "m" } > db.stu.update({gender:'m'},{$set:{gender:'male'}},{multi:true}); WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 }) > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } > 如果有就修改,如果没有就插入(创建)这个文档 > > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } > db.stu.update({name:'xiaoma'},{$set:{name:'xiaomaguohe'}}) #不加这个参数,没有存在的文档就没有任务改变 WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 }) > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } > db.stu.update({name:'xiaoma'},{$set:{name:'xiaomaguohe'}},{upsert:true}); #添加了这个upsert参数,那么不存在的文档就直接插入(被创建) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : ObjectId("6220adb9fb2909fab36892ce") }) > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } > 但是上面的语句虽然不存在就插入,但是插入的信息太少,我们还需要其它 属性,比如每个文档都有的gender。这时需要如下命令,添加$setOnInsert:参数了,如果符合不存在且插入,那么同时增加其它字段 > > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } > db.stu.update({name:'xiaoming'},{$set:{name:'xiaohong'},$setOnInsert:{gender:'w'}},{upsert:true}); WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : ObjectId("6220b74ffb2909fab36892cf") }) > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } { "_id" : ObjectId("6220b74ffb2909fab36892cf"), "name" : "xiaohong", "gender" : "w" } #不存在插入,且增加了其它字段gender > 查: 查询所有文档 > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } { "_id" : ObjectId("6220b74ffb2909fab36892cf"), "name" : "xiaohong", "gender" : "w" } > db.stu.find({},{gender:1}) 查所有文档的指定字段(gender),有这个字段的就显示出值,没有的默认只显示_id,没有不需要显示这个_id,需要添加参数设置为0 > > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } { "_id" : ObjectId("6220b74ffb2909fab36892cf"), "name" : "xiaohong", "gender" : "w" } > db.stu.find({},{gender:1}) { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "gender" : "male" } { "_id" : ObjectId("6220adb9fb2909fab36892ce") } { "_id" : ObjectId("6220b74ffb2909fab36892cf"), "gender" : "w" } > > db.stu.find({},{gender:1,_id:0}) { "gender" : "male" } { "gender" : "male" } { "gender" : "w" } { "gender" : "male" } { "gender" : "male" } { } { "gender" : "w" } > 查询满足指定条件的其它字段,且不显示_id。 > db.stu.find(); { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } { "_id" : ObjectId("6220b74ffb2909fab36892cf"), "name" : "xiaohong", "gender" : "w" } > db.stu.find({gender:'male'},{name:1,_id:0}); { "name" : "mcw1" } { "name" : "mm2" } { "name" : "mcw4" } { "name" : "douzhanshengfo" } >
深入查询表达式
查询表达式: 1: 最简单的查询表达式 {filed:value} ,是指查询field列的值为value的文档 2: $ne --- != 查询表达式 {field:{$nq:value}} 作用--查filed列的值 不等于 value 的文档 3: $nin --> not in 4: $all 语法: {field:{$all:[v1,v2..]}} 是指取出 field列是一个数组,且至少包含 v1,v2值 5: $exists 语法: {field:{$exists:1}} 作用: 查询出含有field字段的文档 6: $nor, {$nor,[条件1,条件2]} 是指 所有条件都不满足的文档为真返回 7:用正则表达式查询 以”诺基亚”开头的商品 例:db.goods.find({goods_name:/诺基亚.*/},{goods_name:1}); 8: 用$where表达式来查询 例: db.goods.find({$where:'this.cat_id != 3 && this.cat_id != 11'}); 注意: 用$where查询时, mongodb是把bson结构的二进制数据转换为json结构的对象, 然后比较对象的属性是否满足表达式. 速度较慢 Update时可用的操作符 例: ->db.user.insert({name:'lisi',age:12,sex:'male',height:123,area:'haidian'}); ->db.user.update({name:'lisi'},{$set:{area:'chaoyang'},$unset:{height:1},$inc:{age:1},$rename:{sex:'gender'}}); > db.user.find(); { "_id" : ObjectId("51fc01c4f5de93e1f2856e33"), "age" : 13, "area" : "chaoyang", "gender" : "male", "name" : "lisi" } $setOnInsert ->相当于mysql中的列的默认值
三 查询知识 注:以下查询基于ecshop网站的商品表(ecs_goods) 在练习时可以只取部分列,方便查看. 1: 基础查询 where的练习: 查出满足以下条件的商品 1.1:主键为32的商品 db.goods.find({goods_id:32}); 1.2:不属第3栏目的所有商品($ne) db.goods.find({cat_id:{$ne:3}},{goods_id:1,cat_id:1,goods_name:1}); 1.3:本店价格高于3000元的商品{$gt} db.goods.find({shop_price:{$gt:3000}},{goods_name:1,shop_price:1}); 1.4:本店价格低于或等于100元的商品($lte) db.goods.find({shop_price:{$lte:100}},{goods_name:1,shop_price:1}); 1.5:取出第4栏目或第11栏目的商品($in) db.goods.find({cat_id:{$in:[4,11]}},{goods_name:1,shop_price:1}); 1.6:取出100<=价格<=500的商品($and) db.goods.find({$and:[{price:{$gt:100},{$price:{$lt:500}}}]); 1.7:取出不属于第3栏目且不属于第11栏目的商品($and $nin和$nor分别实现) db.goods.find({$and:[{cat_id:{$ne:3}},{cat_id:{$ne:11}}]},{goods_name:1,cat_id:1}) db.goods.find({cat_id:{$nin:[3,11]}},{goods_name:1,cat_id:1}); db.goods.find({$nor:[{cat_id:3},{cat_id:11}]},{goods_name:1,cat_id:1}); 1.8:取出价格大于100且小于300,或者大于4000且小于5000的商品() db.goods.find({$or:[{$and:[{shop_price:{$gt:100}},{shop_price:{$lt:300}}]},{$and:[{shop_price:{$gt:4000}},{shop_price:{$lt:5000}}]}]},{goods_name:1,shop_price:1}); 1.9:取出goods_id%5 == 1, 即,1,6,11,..这样的商品 db.goods.find({goods_id:{$mod:[5,1]}}); 1.10:取出有age属性的文档 db.stu.find({age:{$exists:1}}); 含有age属性的文档将会被查出 1.11、根据字段值的类型来查找数据 db.foo.find({age:{$type:1}}) 1.12、$all。取指定字段指定多个元素都有的对象。这里是指爱好里都有b和c的, db.stu.find({hobby:{$all:['b','c']}}) 1.13、$where 可以像js那样,用this去做判断 db.goods.find({$where:'this.shop_price>200 && this.shop_price<500 || this.shop_price>3000 && this.shop_price<5000'},{shop_price:1,goods_name:1,_id:0}); 1.14、$regex正则表达式。查询商品名称以诺基亚开头的 db.goods.find({goods_name:{$regex:/^诺基亚.*/}},{goods_name:1,_id:0})
创建环境
现在MySQL中有商品表信息,需要将表中数据导入到mongodb中。我们实现的方法,可以是把数据查询出来然后构建成json格式数据,在插入到mongodb中去 先添加数据,分三次添加,防止终端因为数据量出现插入问题。 > show dbs; local 0.000GB test 0.000GB > use shop switched to db shop > db.goods.insert([{"goods_id":1,"cat_id":4,"goods_name":"KD876","goods_number":1,"click_count":7,"shop_price":1388.00,"add_time":1240902890},{"goods_id":4,"cat_id":8,"goods_name":"\u8bfa\u57fa\u4e9aN85\u539f\u88c5\u5145\u7535\u5668","goods_number":17,"click_count":0,"shop_price":58.00,"add_time":1241422402},{"goods_id":3,"cat_id":8,"goods_name":"\u8bfa\u57fa\u4e9a\u539f\u88c55800\u8033\u673a","goods_number":24,"click_count":3,"shop_price":68.00,"add_time":1241422082},{"goods_id":5,"cat_id":11,"goods_name":"\u7d22\u7231\u539f\u88c5M2\u5361\u8bfb\u5361\u5668","goods_number":8,"click_count":3,"shop_price":20.00,"add_time":1241422518},{"goods_id":6,"cat_id":11,"goods_name":"\u80dc\u521bKINGMAX\u5185\u5b58\u5361","goods_number":15,"click_count":0,"shop_price":42.00,"add_time":1241422573},{"goods_id":7,"cat_id":8,"goods_name":"\u8bfa\u57fa\u4e9aN85\u539f\u88c5\u7acb\u4f53\u58f0\u8033\u673aHS-82","goods_number":20,"click_count":0,"shop_price":100.00,"add_time":1241422785},{"goods_id":8,"cat_id":3,"goods_name":"\u98de\u5229\u6d669@9v","goods_number":1,"click_count":9,"shop_price":399.00,"add_time":1241425512},{"goods_id":9,"cat_id":3,"goods_name":"\u8bfa\u57fa\u4e9aE66","goods_number":4,"click_count":20,"shop_price":2298.00,"add_time":1241511871},{"goods_id":10,"cat_id":3,"goods_name":"\u7d22\u7231C702c","goods_number":7,"click_count":11,"shop_price":1328.00,"add_time":1241965622},{"goods_id":11,"cat_id":3,"goods_name":"\u7d22\u7231C702c","goods_number":1,"click_count":0,"shop_price":1300.00,"add_time":1241966951},{"goods_id":12,"cat_id":3,"goods_name":"\u6469\u6258\u7f57\u62c9A810","goods_number":8,"click_count":13,"shop_price":983.00,"add_time":1245297652}]) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 11, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) > db.goods.insert([{"goods_id":13,"cat_id":3,"goods_name":"\u8bfa\u57fa\u4e9a5320 XpressMusic","goods_number":8,"click_count":13,"shop_price":1311.00,"add_time":1241967762},{"goods_id":14,"cat_id":4,"goods_name":"\u8bfa\u57fa\u4e9a5800XM","goods_number":1,"click_count":6,"shop_price":2625.00,"add_time":1241968492},{"goods_id":15,"cat_id":3,"goods_name":"\u6469\u6258\u7f57\u62c9A810","goods_number":3,"click_count":8,"shop_price":788.00,"add_time":1241968703},{"goods_id":16,"cat_id":2,"goods_name":"\u6052\u57fa\u4f1f\u4e1aG101","goods_number":0,"click_count":3,"shop_price":823.33,"add_time":1241968949},{"goods_id":17,"cat_id":3,"goods_name":"\u590f\u65b0N7","goods_number":1,"click_count":2,"shop_price":2300.00,"add_time":1241969394},{"goods_id":18,"cat_id":4,"goods_name":"\u590f\u65b0T5","goods_number":1,"click_count":0,"shop_price":2878.00,"add_time":1241969533},{"goods_id":19,"cat_id":3,"goods_name":"\u4e09\u661fSGH-F258","goods_number":12,"click_count":7,"shop_price":858.00,"add_time":1241970139},{"goods_id":20,"cat_id":3,"goods_name":"\u4e09\u661fBC01","goods_number":12,"click_count":14,"shop_price":280.00,"add_time":1241970417},{"goods_id":21,"cat_id":3,"goods_name":"\u91d1\u7acb A30","goods_number":40,"click_count":4,"shop_price":2000.00,"add_time":1241970634},{"goods_id":22,"cat_id":3,"goods_name":"\u591a\u666e\u8fbeTouch HD","goods_number":1,"click_count":15,"shop_price":5999.00,"add_time":1241971076}]) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 10, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) > db.goods.insert([{"goods_id":23,"cat_id":5,"goods_name":"\u8bfa\u57fa\u4e9aN96","goods_number":8,"click_count":17,"shop_price":3700.00,"add_time":1241971488},{"goods_id":24,"cat_id":3,"goods_name":"P806","goods_number":100,"click_count":35,"shop_price":2000.00,"add_time":1241971981},{"goods_id":25,"cat_id":13,"goods_name":"\u5c0f\u7075\u901a\/\u56fa\u8bdd50\u5143\u5145\u503c\u5361","goods_number":2,"click_count":0,"shop_price":48.00,"add_time":1241972709},{"goods_id":26,"cat_id":13,"goods_name":"\u5c0f\u7075\u901a\/\u56fa\u8bdd20\u5143\u5145\u503c\u5361","goods_number":2,"click_count":0,"shop_price":19.00,"add_time":1241972789},{"goods_id":27,"cat_id":15,"goods_name":"\u8054\u901a100\u5143\u5145\u503c\u5361","goods_number":2,"click_count":0,"shop_price":95.00,"add_time":1241972894},{"goods_id":28,"cat_id":15,"goods_name":"\u8054\u901a50\u5143\u5145\u503c\u5361","goods_number":0,"click_count":0,"shop_price":45.00,"add_time":1241972976},{"goods_id":29,"cat_id":14,"goods_name":"\u79fb\u52a8100\u5143\u5145\u503c\u5361","goods_number":0,"click_count":0,"shop_price":90.00,"add_time":1241973022},{"goods_id":30,"cat_id":14,"goods_name":"\u79fb\u52a820\u5143\u5145\u503c\u5361","goods_number":9,"click_count":1,"shop_price":18.00,"add_time":1241973114},{"goods_id":31,"cat_id":3,"goods_name":"\u6469\u6258\u7f57\u62c9E8 ","goods_number":1,"click_count":5,"shop_price":1337.00,"add_time":1242110412},{"goods_id":32,"cat_id":3,"goods_name":"\u8bfa\u57fa\u4e9aN85","goods_number":4,"click_count":9,"shop_price":3010.00,"add_time":1242110760}]) BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 10, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }) > 查看商品信息: > > db.goods.find() { "_id" : ObjectId("6220c20817f568e0f31e12e0"), "goods_id" : 1, "cat_id" : 4, "goods_name" : "KD876", "goods_number" : 1, "click_count" : 7, "shop_price" : 1388, "add_time" : 1240902890 } { "_id" : ObjectId("6220c20817f568e0f31e12e1"), "goods_id" : 4, "cat_id" : 8, "goods_name" : "诺基亚N85原装充电器", "goods_number" : 17, "click_count" : 0, "shop_price" : 58, "add_time" : 1241422402 } { "_id" : ObjectId("6220c20817f568e0f31e12e2"), "goods_id" : 3, "cat_id" : 8, "goods_name" : "诺基亚原装5800耳机", "goods_number" : 24, "click_count" : 3, "shop_price" : 68, "add_time" : 1241422082 } { "_id" : ObjectId("6220c20817f568e0f31e12e3"), "goods_id" : 5, "cat_id" : 11, "goods_name" : "索爱原装M2卡读卡器", "goods_number" : 8, "click_count" : 3, "shop_price" : 20, "add_time" : 1241422518 } { "_id" : ObjectId("6220c20817f568e0f31e12e4"), "goods_id" : 6, "cat_id" : 11, "goods_name" : "胜创KINGMAX内存卡", "goods_number" : 15, "click_count" : 0, "shop_price" : 42, "add_time" : 1241422573 } { "_id" : ObjectId("6220c20817f568e0f31e12e5"), "goods_id" : 7, "cat_id" : 8, "goods_name" : "诺基亚N85原装立体声耳机HS-82", "goods_number" : 20, "click_count" : 0, "shop_price" : 100, "add_time" : 1241422785 } { "_id" : ObjectId("6220c20817f568e0f31e12e6"), "goods_id" : 8, "cat_id" : 3, "goods_name" : "飞利浦9@9v", "goods_number" : 1, "click_count" : 9, "shop_price" : 399, "add_time" : 1241425512 } { "_id" : ObjectId("6220c20817f568e0f31e12e7"), "goods_id" : 9, "cat_id" : 3, "goods_name" : "诺基亚E66", "goods_number" : 4, "click_count" : 20, "shop_price" : 2298, "add_time" : 1241511871 } { "_id" : ObjectId("6220c20817f568e0f31e12e8"), "goods_id" : 10, "cat_id" : 3, "goods_name" : "索爱C702c", "goods_number" : 7, "click_count" : 11, "shop_price" : 1328, "add_time" : 1241965622 } { "_id" : ObjectId("6220c20817f568e0f31e12e9"), "goods_id" : 11, "cat_id" : 3, "goods_name" : "索爱C702c", "goods_number" : 1, "click_count" : 0, "shop_price" : 1300, "add_time" : 1241966951 } { "_id" : ObjectId("6220c20817f568e0f31e12ea"), "goods_id" : 12, "cat_id" : 3, "goods_name" : "摩托罗拉A810", "goods_number" : 8, "click_count" : 13, "shop_price" : 983, "add_time" : 1245297652 } { "_id" : ObjectId("6220c26417f568e0f31e12eb"), "goods_id" : 13, "cat_id" : 3, "goods_name" : "诺基亚5320 XpressMusic", "goods_number" : 8, "click_count" : 13, "shop_price" : 1311, "add_time" : 1241967762 } { "_id" : ObjectId("6220c26417f568e0f31e12ec"), "goods_id" : 14, "cat_id" : 4, "goods_name" : "诺基亚5800XM", "goods_number" : 1, "click_count" : 6, "shop_price" : 2625, "add_time" : 1241968492 } { "_id" : ObjectId("6220c26417f568e0f31e12ed"), "goods_id" : 15, "cat_id" : 3, "goods_name" : "摩托罗拉A810", "goods_number" : 3, "click_count" : 8, "shop_price" : 788, "add_time" : 1241968703 } { "_id" : ObjectId("6220c26417f568e0f31e12ee"), "goods_id" : 16, "cat_id" : 2, "goods_name" : "恒基伟业G101", "goods_number" : 0, "click_count" : 3, "shop_price" : 823.33, "add_time" : 1241968949 } { "_id" : ObjectId("6220c26417f568e0f31e12ef"), "goods_id" : 17, "cat_id" : 3, "goods_name" : "夏新N7", "goods_number" : 1, "click_count" : 2, "shop_price" : 2300, "add_time" : 1241969394 } { "_id" : ObjectId("6220c26417f568e0f31e12f0"), "goods_id" : 18, "cat_id" : 4, "goods_name" : "夏新T5", "goods_number" : 1, "click_count" : 0, "shop_price" : 2878, "add_time" : 1241969533 } { "_id" : ObjectId("6220c26417f568e0f31e12f1"), "goods_id" : 19, "cat_id" : 3, "goods_name" : "三星SGH-F258", "goods_number" : 12, "click_count" : 7, "shop_price" : 858, "add_time" : 1241970139 } { "_id" : ObjectId("6220c26417f568e0f31e12f2"), "goods_id" : 20, "cat_id" : 3, "goods_name" : "三星BC01", "goods_number" : 12, "click_count" : 14, "shop_price" : 280, "add_time" : 1241970417 } { "_id" : ObjectId("6220c26417f568e0f31e12f3"), "goods_id" : 21, "cat_id" : 3, "goods_name" : "金立 A30", "goods_number" : 40, "click_count" : 4, "shop_price" : 2000, "add_time" : 1241970634 } Type "it" for more > 查看集合中有多少条数据(文档): > > db.goods.find().count(); 31 >
问题解决过程(命令执行过程)
三 查询知识 注:以下查询基于ecshop网站的商品表(ecs_goods) 在练习时可以只取部分列,方便查看. 1: 基础查询 where的练习: 查出满足以下条件的商品 1.1:主键为32的商品 db.goods.find({goods_id:32}); > db.goods.find({goods_id:32}); { "_id" : ObjectId("6220c28917f568e0f31e12fe"), "goods_id" : 32, "cat_id" : 3, "goods_name" : "诺基亚N85", "goods_number" : 4, "click_count" : 9, "shop_price" : 3010, "add_time" : 1242110760 } > 1.2:不属第3栏目的所有商品($ne) db.goods.find({cat_id:{$ne:3}},{goods_id:1,cat_id:1,goods_name:1}); 前面是条件表达式,后面是相当于select后面的取哪些字段 > > db.goods.find({cat_id:{$ne:3}},{goods_id:1,cat_id:1,goods_name:1}); { "_id" : ObjectId("6220c20817f568e0f31e12e0"), "goods_id" : 1, "cat_id" : 4, "goods_name" : "KD876" } { "_id" : ObjectId("6220c20817f568e0f31e12e1"), "goods_id" : 4, "cat_id" : 8, "goods_name" : "诺基亚N85原装充电器" } { "_id" : ObjectId("6220c20817f568e0f31e12e2"), "goods_id" : 3, "cat_id" : 8, "goods_name" : "诺基亚原装5800耳机" } { "_id" : ObjectId("6220c20817f568e0f31e12e3"), "goods_id" : 5, "cat_id" : 11, "goods_name" : "索爱原装M2卡读卡器" } { "_id" : ObjectId("6220c20817f568e0f31e12e4"), "goods_id" : 6, "cat_id" : 11, "goods_name" : "胜创KINGMAX内存卡" } { "_id" : ObjectId("6220c20817f568e0f31e12e5"), "goods_id" : 7, "cat_id" : 8, "goods_name" : "诺基亚N85原装立体声耳机HS-82" } { "_id" : ObjectId("6220c26417f568e0f31e12ec"), "goods_id" : 14, "cat_id" : 4, "goods_name" : "诺基亚5800XM" } { "_id" : ObjectId("6220c26417f568e0f31e12ee"), "goods_id" : 16, "cat_id" : 2, "goods_name" : "恒基伟业G101" } { "_id" : ObjectId("6220c26417f568e0f31e12f0"), "goods_id" : 18, "cat_id" : 4, "goods_name" : "夏新T5" } { "_id" : ObjectId("6220c28917f568e0f31e12f5"), "goods_id" : 23, "cat_id" : 5, "goods_name" : "诺基亚N96" } { "_id" : ObjectId("6220c28917f568e0f31e12f7"), "goods_id" : 25, "cat_id" : 13, "goods_name" : "小灵通/固话50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f8"), "goods_id" : 26, "cat_id" : 13, "goods_name" : "小灵通/固话20元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f9"), "goods_id" : 27, "cat_id" : 15, "goods_name" : "联通100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fa"), "goods_id" : 28, "cat_id" : 15, "goods_name" : "联通50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fb"), "goods_id" : 29, "cat_id" : 14, "goods_name" : "移动100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fc"), "goods_id" : 30, "cat_id" : 14, "goods_name" : "移动20元充值卡" } > 1.3:本店价格高于3000元的商品{$gt} (小于是$lt) db.goods.find({shop_price:{$gt:3000}},{goods_name:1,shop_price:1}); > db.goods.find({shop_price:{$gt:3000}},{goods_name:1,shop_price:1}); { "_id" : ObjectId("6220c26417f568e0f31e12f4"), "goods_name" : "多普达Touch HD", "shop_price" : 5999 } { "_id" : ObjectId("6220c28917f568e0f31e12f5"), "goods_name" : "诺基亚N96", "shop_price" : 3700 } { "_id" : ObjectId("6220c28917f568e0f31e12fe"), "goods_name" : "诺基亚N85", "shop_price" : 3010 } > 1.4:本店价格低于或等于100元的商品($lte) db.goods.find({shop_price:{$lte:100}},{goods_name:1,shop_price:1}); > > db.goods.find({shop_price:{$lte:100}},{goods_name:1,shop_price:1}); { "_id" : ObjectId("6220c20817f568e0f31e12e1"), "goods_name" : "诺基亚N85原装充电器", "shop_price" : 58 } { "_id" : ObjectId("6220c20817f568e0f31e12e2"), "goods_name" : "诺基亚原装5800耳机", "shop_price" : 68 } { "_id" : ObjectId("6220c20817f568e0f31e12e3"), "goods_name" : "索爱原装M2卡读卡器", "shop_price" : 20 } { "_id" : ObjectId("6220c20817f568e0f31e12e4"), "goods_name" : "胜创KINGMAX内存卡", "shop_price" : 42 } { "_id" : ObjectId("6220c20817f568e0f31e12e5"), "goods_name" : "诺基亚N85原装立体声耳机HS-82", "shop_price" : 100 } { "_id" : ObjectId("6220c28917f568e0f31e12f7"), "goods_name" : "小灵通/固话50元充值卡", "shop_price" : 48 } { "_id" : ObjectId("6220c28917f568e0f31e12f8"), "goods_name" : "小灵通/固话20元充值卡", "shop_price" : 19 } { "_id" : ObjectId("6220c28917f568e0f31e12f9"), "goods_name" : "联通100元充值卡", "shop_price" : 95 } { "_id" : ObjectId("6220c28917f568e0f31e12fa"), "goods_name" : "联通50元充值卡", "shop_price" : 45 } { "_id" : ObjectId("6220c28917f568e0f31e12fb"), "goods_name" : "移动100元充值卡", "shop_price" : 90 } { "_id" : ObjectId("6220c28917f568e0f31e12fc"), "goods_name" : "移动20元充值卡", "shop_price" : 18 } > 1.5:取出第4栏目或第11栏目的商品($in) db.goods.find({cat_id:{$in:[4,11]}},{goods_name:1,shop_price:1}); > > db.goods.find({cat_id:{$in:[4,11]}},{goods_name:1,shop_price:1}); { "_id" : ObjectId("6220c20817f568e0f31e12e0"), "goods_name" : "KD876", "shop_price" : 1388 } { "_id" : ObjectId("6220c20817f568e0f31e12e3"), "goods_name" : "索爱原装M2卡读卡器", "shop_price" : 20 } { "_id" : ObjectId("6220c20817f568e0f31e12e4"), "goods_name" : "胜创KINGMAX内存卡", "shop_price" : 42 } { "_id" : ObjectId("6220c26417f568e0f31e12ec"), "goods_name" : "诺基亚5800XM", "shop_price" : 2625 } { "_id" : ObjectId("6220c26417f568e0f31e12f0"), "goods_name" : "夏新T5", "shop_price" : 2878 } > 1.6:取出100<=价格<=500的商品($and) db.goods.find({$and:[{shop_price:{$gte:100}},{shop_price:{$lte:500}}]},{goods_name:1,shop_price:1}); {{$and:[{条件1},{条件2}]},{要查询的字段}} 条件一般是:字段:{$xxx:xxx} > > db.goods.find({$and:[{shop_price:{$gte:100}},{shop_price:{$lte:500}}]},{goods_name:1,shop_price:1}); { "_id" : ObjectId("6220c20817f568e0f31e12e5"), "goods_name" : "诺基亚N85原装立体声耳机HS-82", "shop_price { "_id" : ObjectId("6220c20817f568e0f31e12e6"), "goods_name" : "飞利浦9@9v", "shop_price" : 399 } { "_id" : ObjectId("6220c26417f568e0f31e12f2"), "goods_name" : "三星BC01", "shop_price" : 280 } > 1.7:取出不属于第3栏目且不属于第11栏目的商品($and $nin和$nor分别实现) db.goods.find({$and:[{cat_id:{$ne:3}},{cat_id:{$ne:11}}]},{goods_name:1,cat_id:1}) db.goods.find({cat_id:{$nin:[3,11]}},{goods_name:1,cat_id:1}); db.goods.find({$nor:[{cat_id:3},{cat_id:11}]},{goods_name:1,cat_id:1}); $and 字段不等于3并且字段不等于11 $nin 字段不在[3,11]里的 $nor 字段是3或者是11的取反(意思就是字段不是3且不是11,这是个数学逻辑问题) 字段不等于3并且字段不等于11 > > db.goods.find({$and:[{cat_id:{$ne:3}},{cat_id:{$ne:11}}]},{goods_name:1,cat_id:1}) { "_id" : ObjectId("6220c20817f568e0f31e12e0"), "cat_id" : 4, "goods_name" : "KD876" } { "_id" : ObjectId("6220c20817f568e0f31e12e1"), "cat_id" : 8, "goods_name" : "诺基亚N85原装充电器" } { "_id" : ObjectId("6220c20817f568e0f31e12e2"), "cat_id" : 8, "goods_name" : "诺基亚原装5800耳机" } { "_id" : ObjectId("6220c20817f568e0f31e12e5"), "cat_id" : 8, "goods_name" : "诺基亚N85原装立体声耳机HS-82" } { "_id" : ObjectId("6220c26417f568e0f31e12ec"), "cat_id" : 4, "goods_name" : "诺基亚5800XM" } { "_id" : ObjectId("6220c26417f568e0f31e12ee"), "cat_id" : 2, "goods_name" : "恒基伟业G101" } { "_id" : ObjectId("6220c26417f568e0f31e12f0"), "cat_id" : 4, "goods_name" : "夏新T5" } { "_id" : ObjectId("6220c28917f568e0f31e12f5"), "cat_id" : 5, "goods_name" : "诺基亚N96" } { "_id" : ObjectId("6220c28917f568e0f31e12f7"), "cat_id" : 13, "goods_name" : "小灵通/固话50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f8"), "cat_id" : 13, "goods_name" : "小灵通/固话20元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f9"), "cat_id" : 15, "goods_name" : "联通100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fa"), "cat_id" : 15, "goods_name" : "联通50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fb"), "cat_id" : 14, "goods_name" : "移动100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fc"), "cat_id" : 14, "goods_name" : "移动20元充值卡" } > 字段不在[3,11]里的 > > db.goods.find({cat_id:{$nin:[3,11]}},{goods_name:1,cat_id:1}); { "_id" : ObjectId("6220c20817f568e0f31e12e0"), "cat_id" : 4, "goods_name" : "KD876" } { "_id" : ObjectId("6220c20817f568e0f31e12e1"), "cat_id" : 8, "goods_name" : "诺基亚N85原装充电器" } { "_id" : ObjectId("6220c20817f568e0f31e12e2"), "cat_id" : 8, "goods_name" : "诺基亚原装5800耳机" } { "_id" : ObjectId("6220c20817f568e0f31e12e5"), "cat_id" : 8, "goods_name" : "诺基亚N85原装立体声耳机HS-82" } { "_id" : ObjectId("6220c26417f568e0f31e12ec"), "cat_id" : 4, "goods_name" : "诺基亚5800XM" } { "_id" : ObjectId("6220c26417f568e0f31e12ee"), "cat_id" : 2, "goods_name" : "恒基伟业G101" } { "_id" : ObjectId("6220c26417f568e0f31e12f0"), "cat_id" : 4, "goods_name" : "夏新T5" } { "_id" : ObjectId("6220c28917f568e0f31e12f5"), "cat_id" : 5, "goods_name" : "诺基亚N96" } { "_id" : ObjectId("6220c28917f568e0f31e12f7"), "cat_id" : 13, "goods_name" : "小灵通/固话50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f8"), "cat_id" : 13, "goods_name" : "小灵通/固话20元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f9"), "cat_id" : 15, "goods_name" : "联通100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fa"), "cat_id" : 15, "goods_name" : "联通50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fb"), "cat_id" : 14, "goods_name" : "移动100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fc"), "cat_id" : 14, "goods_name" : "移动20元充值卡" } > nor 字段是3或者是11的取反(意思就是字段不是3且不是11,这是个数学逻辑问题) > > db.goods.find({$nor:[{cat_id:3},{cat_id:11}]},{goods_name:1,cat_id:1}); { "_id" : ObjectId("6220c20817f568e0f31e12e0"), "cat_id" : 4, "goods_name" : "KD876" } { "_id" : ObjectId("6220c20817f568e0f31e12e1"), "cat_id" : 8, "goods_name" : "诺基亚N85原装充电器" } { "_id" : ObjectId("6220c20817f568e0f31e12e2"), "cat_id" : 8, "goods_name" : "诺基亚原装5800耳机" } { "_id" : ObjectId("6220c20817f568e0f31e12e5"), "cat_id" : 8, "goods_name" : "诺基亚N85原装立体声耳机HS-82" } { "_id" : ObjectId("6220c26417f568e0f31e12ec"), "cat_id" : 4, "goods_name" : "诺基亚5800XM" } { "_id" : ObjectId("6220c26417f568e0f31e12ee"), "cat_id" : 2, "goods_name" : "恒基伟业G101" } { "_id" : ObjectId("6220c26417f568e0f31e12f0"), "cat_id" : 4, "goods_name" : "夏新T5" } { "_id" : ObjectId("6220c28917f568e0f31e12f5"), "cat_id" : 5, "goods_name" : "诺基亚N96" } { "_id" : ObjectId("6220c28917f568e0f31e12f7"), "cat_id" : 13, "goods_name" : "小灵通/固话50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f8"), "cat_id" : 13, "goods_name" : "小灵通/固话20元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12f9"), "cat_id" : 15, "goods_name" : "联通100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fa"), "cat_id" : 15, "goods_name" : "联通50元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fb"), "cat_id" : 14, "goods_name" : "移动100元充值卡" } { "_id" : ObjectId("6220c28917f568e0f31e12fc"), "cat_id" : 14, "goods_name" : "移动20元充值卡" } > 1.8:取出价格大于100且小于300,或者大于4000且小于5000的商品(100-300或者4000-5000之间的商品) db.goods.find({$or:[{$and:[{shop_price:{$gt:100}},{shop_price:{$lt:300}}]},{$and:[{shop_price:{$gt:4000}},{shop_price:{$lt:5000}}]}]},{goods_name:1,shop_price:1}); {$or:[{$and:[]},{$and:[]]}]} $and里是这样的[{字段:{}},{字段:{}}] > > db.goods.find({$or:[{$and:[{shop_price:{$gt:100}},{shop_price:{$lt:300}}]},{$and:[{shop_price:{$gt:4000}},{shop_price:{$lt:5000}}]}]},{goods_name:1,shop_price:1}); { "_id" : ObjectId("6220c26417f568e0f31e12f2"), "goods_name" : "三星BC01", "shop_price" : 280 } > 还可以如下去判断,虽然方便写语句,但是好像是效率没上面的高。下面这个价格区间和原文设置的不同,所以返回的数据比较多 > db.goods.find({$where:'this.shop_price>200 && this.shop_price<500 || this.shop_price>3000 && this.shop_price<5000'},{shop_price:1,goods_name:1,_id:0}); { "goods_name" : "飞利浦9@9v", "shop_price" : 399 } { "goods_name" : "三星BC01", "shop_price" : 280 } { "goods_name" : "诺基亚N96", "shop_price" : 3700 } { "goods_name" : "诺基亚N85", "shop_price" : 3010 } > > 1.9:取出goods_id%5 == 1, 即,1,6,11,..这样的商品。 db.goods.find({goods_id:{$mod:[5,1]}}); (规律是id从小到大依次相差都是5,也就都是5的倍数+1。这样的可以使用取模的方式获取id。也就是id除以5,取余数是1的数字。) > > db.goods.find({goods_id:{$mod:[5,1]}}); { "_id" : ObjectId("6220c20817f568e0f31e12e0"), "goods_id" : 1, "cat_id" : 4, "goods_name" : "KD876", "goods_number" : 1, "click_count" : 7, "shop_price" : 1388, "add_time" : 1240902890 } { "_id" : ObjectId("6220c20817f568e0f31e12e4"), "goods_id" : 6, "cat_id" : 11, "goods_name" : "胜创KINGMAX内存卡", "goods_number" : 15, "click_count" : 0, "shop_price" : 42, "add_time" : 1241422573 } { "_id" : ObjectId("6220c20817f568e0f31e12e9"), "goods_id" : 11, "cat_id" : 3, "goods_name" : "索爱C702c", "goods_number" : 1, "click_count" : 0, "shop_price" : 1300, "add_time" : 1241966951 } { "_id" : ObjectId("6220c26417f568e0f31e12ee"), "goods_id" : 16, "cat_id" : 2, "goods_name" : "恒基伟业G101", "goods_number" : 0, "click_count" : 3, "shop_price" : 823.33, "add_time" : 1241968949 } { "_id" : ObjectId("6220c26417f568e0f31e12f3"), "goods_id" : 21, "cat_id" : 3, "goods_name" : "金立 A30", "goods_number" : 40, "click_count" : 4, "shop_price" : 2000, "add_time" : 1241970634 } { "_id" : ObjectId("6220c28917f568e0f31e12f8"), "goods_id" : 26, "cat_id" : 13, "goods_name" : "小灵通/固话20元充值卡", "goods_number" : 2, "click_count" : 0, "shop_price" : 19, "add_time" : 1241972789 } { "_id" : ObjectId("6220c28917f568e0f31e12fd"), "goods_id" : 31, "cat_id" : 3, "goods_name" : "摩托罗拉E8 ", "goods_number" : 1, "click_count" : 5, "shop_price" : 1337, "add_time" : 1242110412 } > 1.10:取出有age属性的文档 db.stu.find({age:{$exists:1}}); 含有age属性的文档将会被查出 > 只有douzhanshengfo有这个属性,所以查出来了,如果查不存在这个属性,就将1改为0就好 > show dbs; local 0.000GB shop 0.000GB test 0.000GB > use test switched to db test > show co CountDownLatch compareOn( connectionURLTheSame( copyDbpath( compare( connect( constructor copyFile( > show collections; stu stup > db.stu.find() { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } { "_id" : ObjectId("6220b74ffb2909fab36892cf"), "name" : "xiaohong", "gender" : "w" } > > > db.stu.find({age:{$exists:1}}); #查出存在这个属性的 { "_id" : ObjectId("6220a72baec42b1cbc12a0ac"), "name" : "douzhanshengfo", "age" : 501, "gender" : "male" } > > > > db.stu.find({age:{$exists:0}}); #查出不存在这个属性的 { "_id" : ObjectId("6220a545aec42b1cbc12a0a8"), "name" : "mcw1", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0a9"), "name" : "mm2", "gender" : "male" } { "_id" : ObjectId("6220a545aec42b1cbc12a0aa"), "name" : "mcw3", "gender" : "w" } { "_id" : ObjectId("6220a545aec42b1cbc12a0ab"), "name" : "mcw4", "gender" : "male" } { "_id" : ObjectId("6220adb9fb2909fab36892ce"), "name" : "xiaomaguohe" } { "_id" : ObjectId("6220b74ffb2909fab36892cf"), "name" : "xiaohong", "gender" : "w" } > 1.11、根据字段值的类型来查找数据 如下,一个是字符串类型的年龄,一个是整型类型的年龄。 当查询指定字段值类型为1的时候,就是整型类型 当查询指定字段值类型为2的时候,就是字符串类型。 可以去官网查 $type,里面有各种类型对应的数字 db.foo.find({age:{$type:1}}) > show collections; stu > db.foo.insert({name:'dingdang',age:'23'}) WriteResult({ "nInserted" : 1 }) > db.foo.insert({name:'xiaoma',age:23}) WriteResult({ "nInserted" : 1 }) > db.foo.find() { "_id" : ObjectId("6220d077ae6f9ca7b52cbc8d"), "name" : "dingdang", "age" : "23" } { "_id" : ObjectId("6220d08dae6f9ca7b52cbc8e"), "name" : "xiaoma", "age" : 23 } > > db.foo.find({age:{$type:1}}) { "_id" : ObjectId("6220d08dae6f9ca7b52cbc8e"), "name" : "xiaoma", "age" : 23 } > > db.foo.find({age:{$type:2}}); { "_id" : ObjectId("6220d077ae6f9ca7b52cbc8d"), "name" : "dingdang", "age" : "23" } > 1.12、$all。取指定字段指定多个元素都有的对象。这里是指爱好里都有b和c的, db.stu.find({hobby:{$all:['b','c']}}) > db.stu.drop(); true > db.stu.insert({name:'lily',hobby:['a','b','c']}); WriteResult({ "nInserted" : 1 }) > db.stu.insert({name:'lycy',hobby:['b','c','e']}); WriteResult({ "nInserted" : 1 }) > db.stu.find({hobby:{$all:['b','c']}}) { "_id" : ObjectId("6220d358ae6f9ca7b52cbc8f"), "name" : "lily", "hobby" : [ "a", "b", "c" ] } { "_id" : ObjectId("6220d36bae6f9ca7b52cbc90"), "name" : "lycy", "hobby" : [ "b", "c", "e" ] } > > db.stu.find({hobby:{$all:['a','c']}}) { "_id" : ObjectId("6220d358ae6f9ca7b52cbc8f"), "name" : "lily", "hobby" : [ "a", "b", "c" ] } > 1.13、$where 可以像js那样,用this去做判断 db.goods.find({$where:'this.shop_price>200 && this.shop_price<500 || this.shop_price>3000 && this.shop_price<5000'},{shop_price:1,goods_name:1,_id:0}); > > db.goods.find({$where:'this.shop_price>5000'},{shop_price:1,goods_name:1,_id:0}); { "goods_name" : "多普达Touch HD", "shop_price" : 5999 } > db.goods.find({$where:'this.shop_price>200 && this.shop_price<500 || this.shop_price>3000 && this.shop_price<5000'},{shop_price:1,goods_name:1,_id:0}); { "goods_name" : "飞利浦9@9v", "shop_price" : 399 } { "goods_name" : "三星BC01", "shop_price" : 280 } { "goods_name" : "诺基亚N96", "shop_price" : 3700 } { "goods_name" : "诺基亚N85", "shop_price" : 3010 } > > 1.14、$regex正则表达式。查询商品名称以诺基亚开头的 db.goods.find({goods_name:{$regex:/^诺基亚.*/}},{goods_name:1,_id:0}) > > db.goods.find({goods_name:{$regex:/^诺基亚.*/}},{goods_name:1,_id:0}) { "goods_name" : "诺基亚N85原装充电器" } { "goods_name" : "诺基亚原装5800耳机" } { "goods_name" : "诺基亚N85原装立体声耳机HS-82" } { "goods_name" : "诺基亚E66" } { "goods_name" : "诺基亚5320 XpressMusic" } { "goods_name" : "诺基亚5800XM" } { "goods_name" : "诺基亚N96" } { "goods_name" : "诺基亚N85" } >
游标操作
游标操作 cursor 游标是什么\? 通俗的说,游标不是查询结果,而是查询的返回资源,或者接口. 通过这个接口,你可以逐条读取. 就像php中的fopen打开文件,得到一个资源一样, 通过资源,可以一行一行的读文件. 声明游标: var cursor = db.collectioName.find(query,projection); Cursor.hasNext() ,判断游标是否已经取到尽头 Cursor. Next() , 取出游标的下1个单元 用while来循环游标 > var mycursor = db.bar.find({_id:{$lte:5}}) > while(mycursor.hasNext()) { ... printjson(mycursor.next()); ... } 例: // 声明游标 var cursor = db.goods.find(); // 循环游标 for(var doc=true;cursor.hasNext();) { printjson(cursor.next());} 也可以简写: for(var cursor=db.goods.find(), doc=true;cursor.hasNext();) { printjson(cursor.next());} 游标还有一个迭代函数,允许我们自定义回调函数来逐个处理每个单元. cursor.forEach(回调函数); 例: > var gettitle = function(obj) {print(obj.goods_name)} > var cursor = db.goods.find(); > cursor.forEach(gettitle); 游标在分页中的应用 比如查到10000行,跳过100页,取10行. 一般地,我们假设每页N行, 当前是page页 就需要跳过前 (page-1)*N 行, 再取N行, 在mysql中, limit offset,N来实现 在mongo中,用skip(), limit()函数来实现的 如 var mycursor = db.bar.find().skip(9995); 则是查询结果中,跳过前9995行 查询第901页,每页10条 则是 var mytcursor = db.bar.find().skip(9000).limit(10); 通过cursor一次性得到所有数据, 并返回数组. 例: >var cursor = db.goods.find(); > printjson(cursor.toArray()); //看到所有行 > printjson(cursor.toArray()[2]); //看到第2行 注意: 不要随意使用toArray() 原因: 会把所有的行立即以对象形式组织在内存里. 可以在取出少数几行时,用此功能.
如果查询的数据量特别大,该怎么办。 mogodb底层解析引擎用js做的,所以可以在mongodb的命令行写个js语句插入一万行数据,模拟大量数据的环境。 > show dbs; local 0.000GB shop 0.000GB test 0.000GB > use test; switched to db test > show tables; foo stu > show collections; foo stu > > for(var i=0;i<10000;i++) { ... db.bar.insert({_id:i+1,title:'hello world',content:'aaa'+i}); ... }; WriteResult({ "nInserted" : 1 }) > db.bar.find().count(); #已经创建了一万条数据 10000 > db.bar.find(); #它不会把一万条都显示出来,只显示前20条,实际应用场景,都是查询显示出多少条数据,而不是一万条都查出来。 { "_id" : 1, "title" : "hello world", "content" : "aaa0" } { "_id" : 2, "title" : "hello world", "content" : "aaa1" } { "_id" : 3, "title" : "hello world", "content" : "aaa2" } { "_id" : 4, "title" : "hello world", "content" : "aaa3" } { "_id" : 5, "title" : "hello world", "content" : "aaa4" } { "_id" : 6, "title" : "hello world", "content" : "aaa5" } { "_id" : 7, "title" : "hello world", "content" : "aaa6" } { "_id" : 8, "title" : "hello world", "content" : "aaa7" } { "_id" : 9, "title" : "hello world", "content" : "aaa8" } { "_id" : 10, "title" : "hello world", "content" : "aaa9" } { "_id" : 11, "title" : "hello world", "content" : "aaa10" } { "_id" : 12, "title" : "hello world", "content" : "aaa11" } { "_id" : 13, "title" : "hello world", "content" : "aaa12" } { "_id" : 14, "title" : "hello world", "content" : "aaa13" } { "_id" : 15, "title" : "hello world", "content" : "aaa14" } { "_id" : 16, "title" : "hello world", "content" : "aaa15" } { "_id" : 17, "title" : "hello world", "content" : "aaa16" } { "_id" : 18, "title" : "hello world", "content" : "aaa17" } { "_id" : 19, "title" : "hello world", "content" : "aaa18" } { "_id" : 20, "title" : "hello world", "content" : "aaa19" } Type "it" for more > > it #当按照提示打印it的时候,往下再打印20个数据 { "_id" : 21, "title" : "hello world", "content" : "aaa20" } { "_id" : 22, "title" : "hello world", "content" : "aaa21" } ........ { "_id" : 39, "title" : "hello world", "content" : "aaa38" } { "_id" : 40, "title" : "hello world", "content" : "aaa39" } Type "it" for more > > var mycusor = db.bar.find(); > var mycusor = db.bar.find({_id:{$lte:5}}) #声明一个游标变量 > print(mycusor) DBQuery: test.bar -> { "_id" : { "$lte" : 5 } } > print(mycusor.next()) #可以看到使用变量点next(),是个BSON数据 [object BSON] > printjson(mycusor.next()) #使用printjson()打印,就能显示具体内容。因为上面游标已经打印取了一次值(id是1)了,这次取值就是id是2的数据 { "_id" : 2, "title" : "hello world", "content" : "aaa1" } > > printjson(mycusor.next()) { "_id" : 3, "title" : "hello world", "content" : "aaa2" } > printjson(mycusor.next()) { "_id" : 4, "title" : "hello world", "content" : "aaa3" } > printjson(mycusor.next()) { "_id" : 5, "title" : "hello world", "content" : "aaa4" } > printjson(mycusor.next()) #继续往下取,发现游标走到头了,没有下一个了 2022-03-04T00:01:02.471+0800 E QUERY [thread1] Error: error hasNext: false : DBQuery.prototype.next@src/mongo/shell/query.js:293:1 @(shell):1:11 > while循环遍历游标 判断只要游标还有下一个,那么我就将它取出来。这里游标只取了前五个数据 > var mycursor = db.bar.find({_id:{$lte:5}}) > while(mycursor.hasNext()) { ... printjson(mycursor.next()); ... } { "_id" : 1, "title" : "hello world", "content" : "aaa0" } { "_id" : 2, "title" : "hello world", "content" : "aaa1" } { "_id" : 3, "title" : "hello world", "content" : "aaa2" } { "_id" : 4, "title" : "hello world", "content" : "aaa3" } { "_id" : 5, "title" : "hello world", "content" : "aaa4" } > for循环遍历游标 > > for(var mycursor=db.bar.find({_id:{$lte:5}}) ; mycursor.hasNext(); ) { ... printjson(mycursor.next()) ... } { "_id" : 1, "title" : "hello world", "content" : "aaa0" } { "_id" : 2, "title" : "hello world", "content" : "aaa1" } { "_id" : 3, "title" : "hello world", "content" : "aaa2" } { "_id" : 4, "title" : "hello world", "content" : "aaa3" } { "_id" : 5, "title" : "hello world", "content" : "aaa4" } > 游标还有一个迭代函数,允许我们自定义回调函数来逐个处理每个单元. cursor.forEach(回调函数);因为创建游标一般都要遍历的,所以直接用这种方法实现遍历 其中obj是游标中每一个元素,这样函数中可以对每个元素做操作。 > > var mycursor = db.bar.find({_id:{$lte:5}}) > mycursor.forEach(function(obj){printjson(obj)}); { "_id" : 1, "title" : "hello world", "content" : "aaa0" } { "_id" : 2, "title" : "hello world", "content" : "aaa1" } { "_id" : 3, "title" : "hello world", "content" : "aaa2" } { "_id" : 4, "title" : "hello world", "content" : "aaa3" } { "_id" : 5, "title" : "hello world", "content" : "aaa4" } > 下面我们不想要打印所有了,我们只打印我们需要的信息(id) > > var mycursor = db.bar.find({_id:{$lte:5}}) > mycursor.forEach(function(obj){print('your id is '+obj._id)}); your id is 1 your id is 2 your id is 3 your id is 4 your id is 5 > 游标在分页中的应用 比如查到10000行,跳过100页,取10行. 一般地,我们假设每页N行, 当前是page页 就需要跳过前 (page-1)*N 行, 再取N行, 在mysql中, limit offset,N来实现 在mongo中,用skip(), limit()函数来实现的 如 var mycursor = db.bar.find().skip(9995); 则是查询结果中,跳过前9995行: > var mycursor = db.bar.find().skip(9995); #跳过前9995行,直接取后面的数据,是9996-10000行的数据,跳过之后有多少行取多少行 > mycursor.forEach(function(obj){printjson(obj)}); { "_id" : 9996, "title" : "hello world", "content" : "aaa9995" } { "_id" : 9997, "title" : "hello world", "content" : "aaa9996" } { "_id" : 9998, "title" : "hello world", "content" : "aaa9997" } { "_id" : 9999, "title" : "hello world", "content" : "aaa9998" } { "_id" : 10000, "title" : "hello world", "content" : "aaa9999" } > 查询第901页,每页10条 则是 var mycursor = db.bar.find().skip(9000).limit(10); skip是跳过多少行,limit是限制前多少行,两者结合就可以取中间的指定区间 > > var mycursor = db.bar.find().skip(9000).limit(10); > mycursor.forEach(function(obj){printjson(obj)}); { "_id" : 9001, "title" : "hello world", "content" : "aaa9000" } { "_id" : 9002, "title" : "hello world", "content" : "aaa9001" } { "_id" : 9003, "title" : "hello world", "content" : "aaa9002" } { "_id" : 9004, "title" : "hello world", "content" : "aaa9003" } { "_id" : 9005, "title" : "hello world", "content" : "aaa9004" } { "_id" : 9006, "title" : "hello world", "content" : "aaa9005" } { "_id" : 9007, "title" : "hello world", "content" : "aaa9006" } { "_id" : 9008, "title" : "hello world", "content" : "aaa9007" } { "_id" : 9009, "title" : "hello world", "content" : "aaa9008" } { "_id" : 9010, "title" : "hello world", "content" : "aaa9009" } > 通过cursor一次性得到所有数据, 并返回数组. 例: >var cursor = db.goods.find(); > printjson(cursor.toArray()); //看到所有行 > printjson(cursor.toArray()[2]); //看到第2行 注意: 不要随意使用toArray() 原因: 会把所有的行立即以对象形式组织在内存里. 可以在取出少数几行时,用此功能. > > var mycursor = db.bar.find().skip(9000).limit(5); #数量少,不想迭代数据了,直接toArray()就行 > mycursor.toArray(); [ { "_id" : 9001, "title" : "hello world", "content" : "aaa9000" }, { "_id" : 9002, "title" : "hello world", "content" : "aaa9001" }, { "_id" : 9003, "title" : "hello world", "content" : "aaa9002" }, { "_id" : 9004, "title" : "hello world", "content" : "aaa9003" }, { "_id" : 9005, "title" : "hello world", "content" : "aaa9004" } ] > 假如我不想要那么多数据,我只需要最后那个数据,因为返回的是个数组,直接索引取值就可以 > > var mycursor = db.bar.find().skip(9000).limit(5); > print(mycursor.toArray()[4]); [object BSON] > var mycursor = db.bar.find().skip(9000).limit(5); > printjson(mycursor.toArray()[4]); { "_id" : 9005, "title" : "hello world", "content" : "aaa9004" } >
索引
索引创建 1:索引提高查询速度,降低写入速度,权衡常用的查询字段,不必在太多列上建索引 2.在mongodb中,索引可以按字段升序/降序来创建,便于排序 3.默认是用btree来组织索引文件,2.4版本以后,也允许建立hash索引. 查看查询计划 db.find(query).explain(); "cursor" : "BasicCursor", ----说明没有索引发挥作用 "nscannedObjects" : 1000 ---理论上要扫描多少行 cursor" : "BtreeCursor sn_1", 用到的btree索引 常用命令: 查看当前索引状态: db.collection.getIndexes(); 创建普通的单列索引:db.collection.ensureIndex({field:1/-1}); 1是升续 2是降续 删除单个索引 db.collection.dropIndex({filed:1/-1}); 一下删除所有索引 db.collection.dropIndexes(); 创建多列索引 db.collection.ensureIndex({field1:1/-1, field2:1/-1}); 创建子文档索引 db.collection.ensureIndex({filed.subfield:1/-1}); 创建唯一索引: db.collection.ensureIndex({filed.subfield:1/-1}, {unique:true}); 创建稀疏索引: 稀疏索引的特点------如果针对field做索引,针对不含field列的文档,将不建立索引. 与之相对,普通索引,会把该文档的field列的值认为NULL,并建索引. 适宜于: 小部分文档含有某列时. db.collection.ensureIndex({field:1/-1},{sparse:true}); > db.tea.find(); { "_id" : ObjectId("5275f99b87437c610023597b"), "email" : "a@163.com" } { "_id" : ObjectId("5275f99e87437c610023597c"), "email" : "b@163.com" } { "_id" : ObjectId("5275f9e887437c610023597e"), "email" : "c@163.com" } { "_id" : ObjectId("5275fa3887437c6100235980") } 如上内容,最后一行没有email列, 如果分别加普通索引,和稀疏索引, 对于最后一行的email分别当成null 和 忽略最后一行来处理. 根据{email:null}来查询,前者能查到,而稀疏索引查不到最后一行. 创建哈希索引(2.4新增的) 哈希索引速度比普通索引快,但是,无能对范围查询进行优化. 适宜于---随机性强的散列 db.collection.ensureIndex({file:’hashed’}); 重建索引 一个表经过很多次修改后,导致表的文件产生空洞,索引文件也如此. 可以通过索引的重建,减少索引文件碎片,并提高索引的效率. 类似mysql中的optimize table db.collection.reIndex()
创建环境数据,创建1000条数据 > for(var i=1;i<=1000;i++) { ... db.stu.insert({sn:i,name:'student'+i}) ... } WriteResult({ "nInserted" : 1 }) > db.stu.find().count(); 1000 > db.stu.find(); { "_id" : ObjectId("6220fac3ae6f9ca7b52cbc91"), "sn" : 1, "name" : "student1" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc92"), "sn" : 2, "name" : "student2" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc93"), "sn" : 3, "name" : "student3" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc94"), "sn" : 4, "name" : "student4" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc95"), "sn" : 5, "name" : "student5" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc96"), "sn" : 6, "name" : "student6" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc97"), "sn" : 7, "name" : "student7" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc98"), "sn" : 8, "name" : "student8" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc99"), "sn" : 9, "name" : "student9" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc9a"), "sn" : 10, "name" : "student10" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc9b"), "sn" : 11, "name" : "student11" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc9c"), "sn" : 12, "name" : "student12" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc9d"), "sn" : 13, "name" : "student13" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc9e"), "sn" : 14, "name" : "student14" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbc9f"), "sn" : 15, "name" : "student15" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbca0"), "sn" : 16, "name" : "student16" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbca1"), "sn" : 17, "name" : "student17" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbca2"), "sn" : 18, "name" : "student18" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbca3"), "sn" : 19, "name" : "student19" } { "_id" : ObjectId("6220fac4ae6f9ca7b52cbca4"), "sn" : 20, "name" : "student20" } Type "it" for more > 查看当前索引 > db.stu.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stu" } ] > 当查询计划的结果游标显示是基础游标时,说明没有走索引,如果查第99条数据,那么就会从1顺序往下查,肯定会比较慢。而我这里这个版本的 mongodb,创建好之后直接就使用索引了,好像是的 > db.stu.find({sn:99}) { "_id" : ObjectId("6220fac4ae6f9ca7b52cbcf3"), "sn" : 99, "name" : "student99" } > db.stu.find({sn:99}).explain(); { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.stu", "indexFilterSet" : false, "parsedQuery" : { "sn" : { "$eq" : 99 } }, "winningPlan" : { "stage" : "COLLSCAN", #没有可用索引,所以必须扫描整个集合 "filter" : { "sn" : { "$eq" : 99 } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "serverInfo" : { "host" : "mcw01", "port" : 27017, "version" : "3.2.8", "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0" }, "ok" : 1 } > 当给sn加上索引后: > db.stu.ensureIndex({sn:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.stu.find({sn:99}).explain(); { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.stu", "indexFilterSet" : false, "parsedQuery" : { "sn" : { "$eq" : 99 } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", #索引扫描 "keyPattern" : { "sn" : 1 }, "indexName" : "sn_1", #现在有索引了 "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "sn" : [ "[99.0, 99.0]" ] } } }, "rejectedPlans" : [ ] }, "serverInfo" : { "host" : "mcw01", "port" : 27017, "version" : "3.2.8", "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0" }, "ok" : 1 } > 再次查看,现在有了第二个索引了,新建的索引。id索引是默认就生成的 > db.stu.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stu" }, { "v" : 1, "key" : { "sn" : 1 }, "name" : "sn_1", "ns" : "test.stu" } ] > 降序创建了一个索引 > db.stu.ensureIndex({name:-1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 2, "numIndexesAfter" : 3, "ok" : 1 } > db.stu.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stu" }, { "v" : 1, "key" : { "sn" : 1 }, "name" : "sn_1", "ns" : "test.stu" }, { "v" : 1, "key" : { "name" : -1 }, "name" : "name_-1", "ns" : "test.stu" } ] > 删除name索引,要写上指定的1还是-1(1生序,-1倒序) > db.stu.dropIndex({name:-1}) { "nIndexesWas" : 3, "ok" : 1 } > db.stu.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stu" }, { "v" : 1, "key" : { "sn" : 1 }, "name" : "sn_1", "ns" : "test.stu" } ] > 删除所有的索引,这个不包含_id自带的索引 > > db.stu.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stu" }, { "v" : 1, "key" : { "sn" : 1 }, "name" : "sn_1", "ns" : "test.stu" } ] > db.stu.dropIndexes(); { "nIndexesWas" : 2, "msg" : "non-_id indexes dropped for collection", "ok" : 1 } > db.stu.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stu" } ] > 多列索引创建(相当于MySQL联合索引 > db.stu.ensureIndex({sn:1,name:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.stu.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.stu" }, { "v" : 1, "key" : { "sn" : 1, "name" : 1 }, "name" : "sn_1_name_1", "ns" : "test.stu" } ] > 查询文档子属性(筛选过滤子属性) > > db.shop.insert({name:'Nokia',spec:{weight:120,area:'taiwan'}}); #创建两条数据 WriteResult({ "nInserted" : 1 }) > db.shop.insert({name:'sanxing',spec:{weight:100,area:'hanguo'}}); WriteResult({ "nInserted" : 1 }) > db.shop.find({name:'Nokia'}); #查name的好查 { "_id" : ObjectId("62210561ae6f9ca7b52cc461"), "name" : "Nokia", "spec" : { "weight" : 120, "area" : "taiwan" } } > db.shop.find({area:'taiwan'}); #查子属性这样查不出来 > db.shop.find({spec:{area:'taiwan'}}); #这样也查不出来,因为spec下没有值单独是这样的,它还有其他的属性的。所以就不符合 > db.shop.find({'spec.area':'taiwan'}); #因为点可以取子属性,所以只能让键等于属性点子键,这样就可以查出来了 { "_id" : ObjectId("62210561ae6f9ca7b52cc461"), "name" : "Nokia", "spec" : { "weight" : 120, "area" : "taiwan" } } > 给子文档加索引,(给文档子属性area加索引) > db.shop.find(); { "_id" : ObjectId("62210561ae6f9ca7b52cc461"), "name" : "Nokia", "spec" : { "weight" : 120, "area" : "taiwan" } } { "_id" : ObjectId("62210575ae6f9ca7b52cc462"), "name" : "sanxing", "spec" : { "weight" : 100, "area" : "hanguo" } } > db.shop.ensureIndex({'spec.area':1}); { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.shop.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.shop" }, { "v" : 1, "key" : { "spec.area" : 1 }, "name" : "spec.area_1", "ns" : "test.shop" } ] > 创建唯一索引 > db.tea.insert({email:'a@163.com'}) WriteResult({ "nInserted" : 1 }) > db.tea.insert({email:'b@163.com'}) WriteResult({ "nInserted" : 1 }) > db.tea.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.tea" } ] > db.tea.ensureIndex({email:1},{unique:true}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.tea.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.tea" }, { "v" : 1, "unique" : true, "key" : { "email" : 1 }, "name" : "email_1", "ns" : "test.tea" } ] > #验证如下,不能写入相同的值 > db.tea.insert({email:'c@163.com'}) WriteResult({ "nInserted" : 1 }) > db.tea.insert({email:'c@163.com'}) WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error collection: test.tea index: email_1 dup key: { : \"c@163.com\" }" } }) > 即使文档没有字段也会添加索引 即使null也会被加进索引 > > db.tea.dropIndexes(); { "nIndexesWas" : 2, "msg" : "non-_id indexes dropped for collection", "ok" : 1 } > db.tea.find() { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } > db.tea.insert({}); #插入一个空的文档 WriteResult({ "nInserted" : 1 }) > db.tea.find() { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } { "_id" : ObjectId("622185a612caf24babbda9cc") } > db.tea.ensureIndex({email:1}) #给邮件添加索引 { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.tea.find(); { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } { "_id" : ObjectId("622185a612caf24babbda9cc") } > db.tea.find({email:null}); { "_id" : ObjectId("622185a612caf24babbda9cc") } > db.tea.find({email:null}).explain(); #查看即使是null空的也会使用索引 { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.tea", "indexFilterSet" : false, "parsedQuery" : { "email" : { "$eq" : null } }, "winningPlan" : { "stage" : "FETCH", "filter" : { "email" : { "$eq" : null } }, "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "email" : 1 }, "indexName" : "email_1", "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "email" : [ "[null, null]" ] } } }, "rejectedPlans" : [ ] }, "serverInfo" : { "host" : "mcw01", "port" : 27017, "version" : "3.2.8", "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0" }, "ok" : 1 } > 稀疏索引,我这里添加{sparse:true},然后再查询null不存在的字段时,显示的是COLLSCAN不走索引了,跟上面的不同 > > db.tea.dropIndexes(); { "nIndexesWas" : 2, "msg" : "non-_id indexes dropped for collection", "ok" : 1 } > db.tea.ensureIndex({email:1},{sparse:true}); { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.tea.find({email:null}) { "_id" : ObjectId("622185a612caf24babbda9cc") } > db.tea.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.tea" }, { "v" : 1, "key" : { "email" : 1 }, "name" : "email_1", "ns" : "test.tea", "sparse" : true } ] > > db.tea.find({email:null}).explain(); { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.tea", "indexFilterSet" : false, "parsedQuery" : { "email" : { "$eq" : null } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "email" : { "$eq" : null } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "serverInfo" : { "host" : "mcw01", "port" : 27017, "version" : "3.2.8", "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0" }, "ok" : 1 } > 创建哈希索引 > db.tea.dropIndexes(); { "nIndexesWas" : 2, "msg" : "non-_id indexes dropped for collection", "ok" : 1 } > db.tea.ensureIndex({email:'hashed'}); #创建哈希索引。给字段 { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } > db.tea.find({email:'a@163.com'}); { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } > db.tea.find({email:'a@163.com'}).explain(); { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.tea", "indexFilterSet" : false, "parsedQuery" : { "email" : { "$eq" : "a@163.com" } }, "winningPlan" : { "stage" : "FETCH", "filter" : { "email" : { "$eq" : "a@163.com" } }, "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "email" : "hashed" }, "indexName" : "email_hashed", "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "email" : [ "[2069420833715827975, 2069420833715827975]" ] } } }, "rejectedPlans" : [ ] }, "serverInfo" : { "host" : "mcw01", "port" : 27017, "version" : "3.2.8", "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0" }, "ok" : 1 } > 重建索引 > db.tea.getIndexes(); [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.tea" }, { "v" : 1, "key" : { "email" : "hashed" }, "name" : "email_hashed", "ns" : "test.tea" } ] > db.tea.reIndex(); { "nIndexesWas" : 2, "nIndexes" : 2, "indexes" : [ { "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "test.tea" }, { "key" : { "email" : "hashed" }, "name" : "email_hashed", "ns" : "test.tea" } ], "ok" : 1 } >
用户管理
0: 查看用户 1: 添加用户 命令:db.addUser(); 简单参数: db.addUser(用户名,密码,是否只读) 注意: 添加用户后,我们再次退出并登陆,发现依然可以直接读数据库? 原因: mongodb服务器启动时, 默认不是需要认证的. 要让用户生效, 需要启动服务器时,就指定 --auth 选项. 这样, 操作时,就需要认证了. 例: 1: 添加用户 > use admin > db.addUser(‘sa’,’sa’,false); 2: 认证 > use test > db.auth(用户名,密码); 3: 修改用户密码 > use test > db.changeUserPassword(用户名, 新密码); 3:删除用户 > use test > db.removeUser(用户名); 注: 如果需要给用户添加更多的权限,可以用json结构来传递用户参数 例: > use test >db.addUser({user:'guan',pwd:'111111',roles:['readWrite,dbAdmin']});
--admin db.createUser( { user: "root", pwd: "root", roles: [ { role: "root", db: "admin" } ] } ) db.auth("root","root") mongod.conf需加入开启验证,并重启 auth=true 先登录到admin数据库 --test use test db.createUser( { user: "test", pwd: "test", roles: [ { role: "read", db: "test" } ] } ) db.auth("test","test") db.createCollection('b') db.createUser( { user: "test1", pwd: "test1", roles: [ { role: "readWrite", db: "test" } ] } ) db.auth("test1","test1") --app use app db.createUser( { user: "app", pwd: "app", roles: [ { role: "read", db: "app" } ] } ) db.auth("app","app") use app db.dropUser("app") //删除用户 --auth 启用安全认证之后连接方式如下: # mongo -uroot -pgrjin 192.168.1.24/admin # mongo -utest -ptest 192.168.1.24/test # mongo -uapp -papp 192.168.1.24/app 补充: ==用户管理 MongoDB数据库默认是没有用户名及密码的,即无权限访问限制。为了方便数据库的管理和安全,需创建数据库用户。 1、创建用户 admin数据库 --创建超级管理员:管理所有数据库 # mongo -uroot -pgrjin 192.168.1.24/admin use admin db.createUser( { user: "root", pwd: "root123", roles: [ { role: "root", db: "admin" } ] } ) db.auth('root','root123') 自定义数据库 创建app数据库的管理员:先登录到admin数据库 # mongo -uroot -pgrjin 192.168.1.24/admin use app db.createUser( { user: "admin", pwd: "admin", roles: [ { role: "dbAdmin", db: "app" } ] } ) db.auth('admin','admin') 创建app数据库读写权限的用户: use app db.createUser( { user: "app01", pwd: "app01", roles: [ "readWrite" ] } ) db.auth('app01','app01') db.createUser( { user: "app02", pwd: "app02", roles: [ "read" ] } ) db.auth('app02','app02') 创建app数据库读写权限的用户并对test数据库具有读权限: use app db.createUser( { user: "app03", pwd: "app03", roles: [ { role: "readWrite", db: "app" }, { role: "read", db: "test" } ] } ) db.auth('app03','app03') 创建app数据库读写权限的用户并具有clusterAdmin权限: use app db.createUser( { user: "app04", pwd: "app04", roles: [ { role: "readWrite", db: "app" }, { role: "clusterAdmin", db: "admin" } ] } ) db.auth('app04','app04') 2、删除用户 删除app01用户:先登录到admin数据库 # mongo -uroot -pgrjin 192.168.1.24/admin use app db.dropUser("app01")
创建用户 > use admin switched to db admin > db.createUser( ... { ... user: "root", ... pwd: "root123", ... roles: [ { role: "root", db: "admin" } ] ... } ... ) Successfully added user: { "user" : "root", "roles" : [ { "role" : "root", "db" : "admin" } ] } > > db.auth('root','root123') 1 > 退出去重新登录,还是不需要密码就登录了,不需要验证 [mongod@mcw01 ~]$ mongo MongoDB shell version: 3.2.8 connecting to: test Server has startup warnings: .... > show dbs; admin 0.000GB local 0.000GB shop 0.000GB test 0.001GB 查看mongod进程,可以看到是没有加认证参数的。停掉进程,重新加--auth的认证参数启动mongodb,然后就需要认证才能访问mongodb了 [mongod@mcw01 ~]$ ps -ef|grep mongo mongod 15778 1 1 Mar03 ? 00:14:48 mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork root 16595 16566 0 10:57 pts/0 00:00:00 su - mongod mongod 16596 16595 0 10:57 pts/0 00:00:00 -bash mongod 16674 16596 0 12:03 pts/0 00:00:00 ps -ef mongod 16675 16596 0 12:03 pts/0 00:00:00 grep --color=auto mongo [mongod@mcw01 ~]$ kill -2 15778 [mongod@mcw01 ~]$ ps -ef|grep mongo root 16595 16566 0 10:57 pts/0 00:00:00 su - mongod mongod 16596 16595 0 10:57 pts/0 00:00:00 -bash mongod 16679 16596 0 12:06 pts/0 00:00:00 ps -ef mongod 16680 16596 0 12:06 pts/0 00:00:00 grep --color=auto mongo [mongod@mcw01 ~]$ mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork --auth #添加认证参数--auth启动 about to fork child process, waiting until server is ready for connections. forked process: 16683 child process started successfully, parent exiting [mongod@mcw01 ~]$ ps -ef|grep mongo root 16595 16566 0 10:57 pts/0 00:00:00 su - mongod mongod 16596 16595 0 10:57 pts/0 00:00:00 -bash mongod 16683 1 62 12:06 ? 00:00:11 mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork --auth mongod 16700 16596 0 12:07 pts/0 00:00:00 ps -ef mongod 16701 16596 0 12:07 pts/0 00:00:00 grep --color=auto mongo 现在虽然登录的时候没有输入用户和密码,但时查询信息是需要认证,才能访问的 [mongod@mcw01 ~]$ mongo MongoDB shell version: 3.2.8 connecting to: test > show dbs; 2022-03-04T12:07:17.378+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:761:19 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 > db.auth('root','root123') #账号认证 Error: Authentication failed. 0 > use admin switched to db admin > db.auth('root','root123') #账号认证也在创建用户的的库中。这里的超级管理员账号是在admin下创建的,认证也要切换到admin库中。 1 > show tables; system.users system.version > show dbs; admin 0.000GB local 0.000GB shop 0.000GB test 0.001GB > use test; #认证后,当需要进入其它库,切换就行,如果有权限的话,那么正常访问 switched to db test > show tables; bar foo shop stu tea > db.tea.find(); { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } { "_id" : ObjectId("622185a612caf24babbda9cc") } > 当我切换到其它库创建一个账号后,发现只能在当前库中做操作,其它库虽然也能切换进入,但是只能切换却做不了其它操作 > use test switched to db test > db.createUser( #test库中创建用户 ... { ... user: "app02", ... pwd: "app02", ... roles: [ "read" ] ... } ... ) Successfully added user: { "user" : "app02", "roles" : [ "read" ] } > bye [mongod@mcw01 ~]$ mongo MongoDB shell version: 3.2.8 connecting to: test > show dbs; #不能查看 2022-03-04T12:18:38.412+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:761:19 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 > show tables; 2022-03-04T12:18:44.031+0800 E QUERY [thread1] Error: listCollections failed: { "ok" : 0, "errmsg" : "not authorized on test to execute command { listCollections: 1.0, filter: {} }", "code" : 13 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:773:1 DB.prototype.getCollectionInfos@src/mongo/shell/db.js:785:19 DB.prototype.getCollectionNames@src/mongo/shell/db.js:796:16 shellHelper.show@src/mongo/shell/utils.js:754:9 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 > db.auth('app01','app01') Error: Authentication failed. 0 > db.auth('app02','app02') #账号认证后 1 > show dbs; #还是不能查看 2022-03-04T12:19:22.130+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:761:19 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 > show tables; #但是能查看到test库本身的数据 bar foo shop stu tea > db.tea.find(); #可以查看本身库的 { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } { "_id" : ObjectId("622185a612caf24babbda9cc") } > use admin #可以切换到其它库 switched to db admin > show dbs; # 2022-03-04T12:20:18.445+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:761:19 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 > use shop # switched to db shop > show tables; #切换到其它库但是并不能查看内容 2022-03-04T12:20:53.754+0800 E QUERY [thread1] Error: listCollections failed: { "ok" : 0, "errmsg" : "not authorized on shop to execute command { listCollections: 1.0, filter: {} }", "code" : 13 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:773:1 DB.prototype.getCollectionInfos@src/mongo/shell/db.js:785:19 DB.prototype.getCollectionNames@src/mongo/shell/db.js:796:16 shellHelper.show@src/mongo/shell/utils.js:754:9 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 > > use app switched to db app > use app switched to db app > db.createUser( #切换到不存在的库app,创建集群admin用户,发现创建失败,因为我当前是app2账号 ... { ... user: "app04", ... pwd: "app04", ... roles: [ { role: "readWrite", db: "app" }, ... { role: "clusterAdmin", db: "admin" } ... ] ... } ... ) 2022-03-04T12:26:14.524+0800 E QUERY [thread1] Error: couldn't add user: not authorized on app to execute command { createUser: "app04", pwd: "xxx", roles: [ { role: "readWrite", db: "app" }, { role: "clusterAdmin", db: "admin" } ], digestPassword: false, writeConcern: { w: "majority", wtimeout: 30000.0 } } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 DB.prototype.createUser@src/mongo/shell/db.js:1267:15 @(shell):1:1 > db.auth('root','root123') #在test库中认证在admin库中创建的超级用户root,认证失败 Error: Authentication failed. 0 > use admin switched to db admin > db.auth('root','root123') #切换到admin用户,认证root用户成功,看来是哪个库创建就得进入哪个库进行认证。 1 > use app switched to db app ##切换到不存在的库app,创建集群admin用户 > db.createUser( ... { ... user: "app04", ... pwd: "app04", ... roles: [ { role: "readWrite", db: "app" }, ... { role: "clusterAdmin", db: "admin" } ... ] ... } ... ) Successfully added user: { "user" : "app04", "roles" : [ { "role" : "readWrite", "db" : "app" }, { "role" : "clusterAdmin", "db" : "admin" } ] } > > db.auth('app04','app04') 1 > bye [mongod@mcw01 ~]$ mongo MongoDB shell version: 3.2.8 connecting to: test > db.auth('app04','app04') #刚刚创建的集群admin用户认证 Error: Authentication failed. 0 > use admin switched to db admin > db.auth('app04','app04') # Error: Authentication failed. 0 > use app switched to db app > db.auth('app04','app04') #得切换到创建账号的app库中认证,成功认证 1 > show dbs; #能查询dbs。而普通用户是不能查询dbs admin 0.000GB local 0.000GB shop 0.000GB test 0.001GB > use test; # switched to db test > show tables; #切换到其它库中,依然不能查看到数据 2022-03-04T12:29:53.649+0800 E QUERY [thread1] Error: listCollections failed: { "ok" : 0, "errmsg" : "not authorized on test to execute command { listCollections: 1.0, filter: {} }", "code" : 13 } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:773:1 DB.prototype.getCollectionInfos@src/mongo/shell/db.js:785:19 DB.prototype.getCollectionNames@src/mongo/shell/db.js:796:16 shellHelper.show@src/mongo/shell/utils.js:754:9 shellHelper@src/mongo/shell/utils.js:651:15 @(shellhelp2):1:1 > 当我在root账号认证的情况下,做如下操作。我要再添加一个超级管理员账号 use admin db.createUser( { user: "mcw01", pwd: "mcw123", roles: [ { role: "root", db: "admin" } ] } ) > > use admin switched to db admin #角色不是随便写的,mcw是不存在的 > db.createUser( ... { ... user: "mcw01", ... pwd: "mcw123", ... roles: [ { role: "mcw", db: "admin" } ] ... } ... ) 2022-03-04T12:42:04.652+0800 E QUERY [thread1] Error: couldn't add user: No role named mcw@admin : _getErrorWithCode@src/mongo/shell/utils.js:25:13 DB.prototype.createUser@src/mongo/shell/db.js:1267:15 @(shell):1:1 > use admin switched to db admin > db.createUser( ... { ... user: "mcw01", ... pwd: "mcw123", ... roles: [ { role: "root", db: "admin" } ] #角色root是存在的,要再创建,就需要指定是root角色才能成功 ... } ... ) Successfully added user: { "user" : "mcw01", "roles" : [ { "role" : "root", "db" : "admin" } ] } > > db.auth('mcw01','mcw123') #当用新的超级用户认证后 1 > use test; switched to db test > show tables; #可以查看其它库的信息 bar foo shop stu tea > db.tea.find(); { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } { "_id" : ObjectId("622185a612caf24babbda9cc") } > > use admin switched to db admin > db.auth('root','root123') #并且其它超级账号并不受影响 1 > > use test; switched to db test > db.tea.find(); { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } { "_id" : ObjectId("622185a612caf24babbda9cc") } > 当命令行使用账号密码正常登录数据库后,进入之后就不需要的db.auth认证了 [mongod@mcw01 ~]$ mongo -uroot -proot12 10.0.0.11/admin MongoDB shell version: 3.2.8 connecting to: 10.0.0.11/admin 2022-03-04T13:02:35.777+0800 E QUERY [thread1] Error: Authentication failed. : DB.prototype._authOrThrow@src/mongo/shell/db.js:1441:20 @(auth):6:1 @(auth):1:2 exception: login failed [mongod@mcw01 ~]$ mongo -uroot -proot123 10.0.0.11/admin MongoDB shell version: 3.2.8 connecting to: 10.0.0.11/admin Server has startup warnings: 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 4096 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files. 2022-03-04T12:06:57.590+0800 I CONTROL [initandlisten] > show dbs; admin 0.000GB local 0.000GB shop 0.000GB test 0.001GB > use test; switched to db test > db.tea.find(); { "_id" : ObjectId("622180a312caf24babbda9c8"), "email" : "a@163.com" } { "_id" : ObjectId("622180a912caf24babbda9c9"), "email" : "b@163.com" } { "_id" : ObjectId("622184a212caf24babbda9ca"), "email" : "c@163.com" } { "_id" : ObjectId("622185a612caf24babbda9cc") } > 查看当前库有哪些用户,切换到库下,show users > use admin switched to db admin > show u UUID( undefined unescape( > show users; { "_id" : "admin.root", "user" : "root", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ] } { "_id" : "admin.mcw01", "user" : "mcw01", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ] } > use app; switched to db app > show users { "_id" : "app.app04", "user" : "app04", "db" : "app", "roles" : [ { "role" : "readWrite", "db" : "app" }, { "role" : "clusterAdmin", "db" : "admin" } ] } { "_id" : "app.admin", "user" : "admin", "db" : "app", "roles" : [ { "role" : "dbAdmin", "db" : "app" } ] } { "_id" : "app.app01", "user" : "app01", "db" : "app", "roles" : [ { "role" : "readWrite", "db" : "app" } ] } { "_id" : "app.app02", "user" : "app02", "db" : "app", "roles" : [ { "role" : "read", "db" : "app" } ] } { "_id" : "app.app03", "user" : "app03", "db" : "app", "roles" : [ { "role" : "readWrite", "db" : "app" }, { "role" : "read", "db" : "test" } ] } > 查看所有用户 > > use admin; switched to db admin > db.system.users.find().pretty(); { "_id" : "admin.root", "user" : "root", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "W34BONpd3A/noEH4Ft+vhA==", "storedKey" : "1Ku/JiQbXUBSoQ4EnvxQ+feCBmU=", "serverKey" : "T2fRczRYFCx2ZRoCo9ExMyxg80A=" } }, "roles" : [ { "role" : "root", "db" : "admin" } ] } { "_id" : "test.app02", "user" : "app02", "db" : "test", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "1rMBdJVCWZ2P5aBdBCjpBw==", "storedKey" : "krB+UMepf/e8r+RrT5ClDFRENPQ=", "serverKey" : "o1K6ZAS6DFf9RpWJEi2NQi3uDIk=" } }, "roles" : [ { "role" : "read", "db" : "test" } ] } { "_id" : "app.app04", "user" : "app04", "db" : "app", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "QJSO13zNgqgEcEmF5HMTwA==", "storedKey" : "s0hhrHEAa5x8jMdwGLBsjtXteD0=", "serverKey" : "jZoFq+z/QmFQuV8q4HmmdYGVfsY=" } }, "roles" : [ { "role" : "readWrite", "db" : "app" }, { "role" : "clusterAdmin", "db" : "admin" } ] } { "_id" : "admin.mcw01", "user" : "mcw01", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "iQui8Me4m+Ma1fQKyNSDuA==", "storedKey" : "1Xg1W8mlEfq5T114L6M1C+CPx9c=", "serverKey" : "Aysk2BDJzgA6iJXP/0jrOy3H9GQ=" } }, "roles" : [ { "role" : "root", "db" : "admin" } ] } { "_id" : "app.admin", "user" : "admin", "db" : "app", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "EtxlpcgOAP+oLROUin6YsA==", "storedKey" : "0wvF22Y8pevLw6jgAZDi8OOYga4=", "serverKey" : "PmoM/Om0VjkY0EcnYt6hfzJETB8=" } }, "roles" : [ { "role" : "dbAdmin", "db" : "app" } ] } { "_id" : "app.app01", "user" : "app01", "db" : "app", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "qurPfQlq+3b2RRnKRjamRA==", "storedKey" : "XXneEG+v/wF1IijopVaEF4osjvo=", "serverKey" : "dxuPsw/w0X+xfkwy7i5qYgwrkKg=" } }, "roles" : [ { "role" : "readWrite", "db" : "app" } ] } { "_id" : "app.app02", "user" : "app02", "db" : "app", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "6v7KBXAbxJhn+x6+Tea/cg==", "storedKey" : "8e1BbBS/LK/sxcUtdszWvSdop0E=", "serverKey" : "oS0SwFA/7IhYkObo57buieFx+ks=" } }, "roles" : [ { "role" : "read", "db" : "app" } ] } { "_id" : "app.app03", "user" : "app03", "db" : "app", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "VCp1fbEtynU2Cs4XD7nJzQ==", "storedKey" : "3+6+CvCpMa9nvMdvpVfOFWEGO3k=", "serverKey" : "nP/kN0zFY05fibtLwuktUr+K61k=" } }, "roles" : [ { "role" : "readWrite", "db" : "app" }, { "role" : "read", "db" : "test" } ] } >