这里有一个与本文同版的思维导图可以下载,基本上包括了MongoDB的方方面面,每个知识点,都有示例代码,有需要的朋友,可以下载下来进一步补充完善。
下载思维导图 MongoDB学习笔记思维导图
mongodb
shell基本操作 启动DB mongod --dbpath d:\mongodb\db 启动shell mongo 127.0.0.1:27017/admin CRUD + - 创建数据库 use foobar 不在当前库中创建集合,新库不会生效,切换到其他库时,刚才的“新库”将不存在 + - 显示所有数据库> show dbs
admin 0.000GB
config 0.000GB
foobar 0.000GB
local 0.000GB
+ - 当前数据库创建表/插入数据 db.persons.insert({name:"uspcat"}) + - 显示所有的表 show collections + - 查询所有数据> db.persons.find()
{ "_id" : ObjectId("5ab9a6f878f483849a9c43f2"), "name" : "uspcat" }
+ - 查询一条数据> db.persons.findOne()
{ "_id" : ObjectId("5ab9a6f878f483849a9c43f2"), "name" : "uspcat" }
+ - 更新> var p = db.persons.findOne()
> p
{ "_id" : ObjectId("5ab9a6f878f483849a9c43f2"), "name" : "uspcat" }
> db.persons.update(p, {name:"uspcat2"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : ObjectId("5ab9a6f878f483849a9c43f2"), "name" : "uspcat2" }
{ "_id" : ObjectId("5ab9a87678f483849a9c43f3"), "name" : "extjs4.2" }
> db.persons.update(p, {age: 21})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : ObjectId("5ab9a6f878f483849a9c43f2"), "age" : 21 }
{ "_id" : ObjectId("5ab9a87678f483849a9c43f3"), "name" : "extjs4.2" }
> db.persons.update({age:21}, {$set:{name:"uspcat3"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
>
> db.persons.find()
{ "_id" : ObjectId("5ab9a6f878f483849a9c43f2"), "age" : 21, "name" : "uspcat3" }
{ "_id" : ObjectId("5ab9a87678f483849a9c43f3"), "name" : "extjs4.2" }
+ - 删除 删除集合中的记录> db.persons.remove({name:"extjs4.2"})
WriteResult({ "nRemoved" : 1 })
> db.persons.find()
{ "_id" : ObjectId("5ab9a6f878f483849a9c43f2"), "age" : 21, "name" : "uspcat3" }
删除集合> db.persons.drop()
true
> show collections
>
删除数据库> db.dropDatabase()
{ "dropped" : "foobar", "ok" : 1 }
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>
help + - db> db.help()
DB methods:
db.adminCommand(nameOrDocument) - switches to 'admin' db, and runs command [just calls db.runCommand(...)]
db.aggregate([pipeline], {options}) - performs a collectionless aggregation on this database; returns a cursor
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.createView(name, viewOn, [{$operator: {...}}, ...], {viewOptions})
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
>
+ - collections> db.persons.help()
DBCollection help
db.persons.find().help() - show DBCursor help
db.persons.bulkWrite( operations, <optional params> ) - bulk execute write operations, optional parameters are: w, wtimeout, j
db.persons.count( query = {}, <optional params> ) - count the number of documents that matches the query, optional parameters are: limit, skip, hint, maxTimeMS
db.persons.copyTo(newColl) - duplicates collection by copying all documents to newColl; no indexes are copied.
db.persons.convertToCapped(maxBytes) - calls {convertToCapped:'persons', size:maxBytes}} command
db.persons.createIndex(keypattern[,options])
db.persons.createIndexes([keypatterns], <options>)
db.persons.dataSize()
db.persons.deleteOne( filter, <optional params> ) - delete first matching document, optional parameters are: w, wtimeout, j
db.persons.deleteMany( filter, <optional params> ) - delete all matching documents, optional parameters are: w, wtimeout, j
db.persons.distinct( key, query, <optional params> ) - e.g. db.persons.distinct( 'x' ), optional parameters are: maxTimeMS
db.persons.drop() drop the collection
db.persons.dropIndex(index) - e.g. db.persons.dropIndex( "indexName" ) or db.persons.dropIndex( { "indexKey" : 1 } )
db.persons.dropIndexes()
db.persons.ensureIndex(keypattern[,options]) - DEPRECATED, use createIndex() instead
db.persons.explain().help() - show explain help
db.persons.reIndex()
db.persons.find([query],[fields]) - query is an optional query filter. fields is optional set of fields to return.
e.g. db.persons.find( {x:77} , {name:1, x:1} )
db.persons.find(...).count()
db.persons.find(...).limit(n)
db.persons.find(...).skip(n)
db.persons.find(...).sort(...)
db.persons.findOne([query], [fields], [options], [readConcern])
db.persons.findOneAndDelete( filter, <optional params> ) - delete first matching document, optional parameters are: projection, sort, maxTimeMS
db.persons.findOneAndReplace( filter, replacement, <optional params> ) - replace first matching document, optional parameters are: projection, sort, maxTimeMS, upsert, returnNewDocument
db.persons.findOneAndUpdate( filter, update, <optional params> ) - update first matching document, optional parameters are: projection, sort, maxTimeMS, upsert, returnNewDocument
db.persons.getDB() get DB object associated with collection
db.persons.getPlanCache() get query plan cache associated with collection
db.persons.getIndexes()
db.persons.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )
db.persons.insert(obj)
db.persons.insertOne( obj, <optional params> ) - insert a document, optional parameters are: w, wtimeout, j
db.persons.insertMany( [objects], <optional params> ) - insert multiple documents, optional parameters are: w, wtimeout, j
db.persons.mapReduce( mapFunction , reduceFunction , <optional params> )
db.persons.aggregate( [pipeline], <optional params> ) - performs an aggregation on a collection; returns a cursor
db.persons.remove(query)
db.persons.replaceOne( filter, replacement, <optional params> ) - replace the first matching document, optional parameters are: upsert, w, wtimeout, j
db.persons.renameCollection( newName , <dropTarget> ) renames the collection.
db.persons.runCommand( name , <options> ) runs a db command with the given name where the first param is the collection name
db.persons.save(obj)
db.persons.stats({scale: N, indexDetails: true/false, indexDetailsKey: <index key>, indexDetailsName: <index name>})
db.persons.storageSize() - includes free space allocated to this collection
db.persons.totalIndexSize() - size in bytes of all the indexes
db.persons.totalSize() - storage allocated for all data and indexes
db.persons.update( query, object[, upsert_bool, multi_bool] ) - instead of two flags, you can pass an object with fields: upsert, multi
db.persons.updateOne( filter, update, <optional params> ) - update the first matching document, optional parameters are: upsert, w, wtimeout, j
db.persons.updateMany( filter, update, <optional params> ) - update all matching documents, optional parameters are: upsert, w, wtimeout, j
db.persons.validate( <full> ) - SLOW
db.persons.getShardVersion() - only for use with sharding
db.persons.getShardDistribution() - prints statistics about data distribution in the cluster
db.persons.getSplitKeysForChunks( <maxChunkSize> ) - calculates split points over all chunks and returns splitter function
db.persons.getWriteConcern() - returns the write concern used for any operations on this collection, inherited from server/db if set
db.persons.setWriteConcern( <write concern doc> ) - sets the write concern for writes to the collection
db.persons.unsetWriteConcern( <write concern doc> ) - unsets the write concern for writes to the collection
db.persons.latencyStats() - display operation latency histograms for this collection
>
+ - 数据库和集合命名规范 不能是空串 不能包含空格、,、$、/、\、\O(空字符) 全部小写 最多64个字节 不能与现有系统保留库同名 admin local config 这样的集合名字是合法的 db-text db-text会被当成减法操作 不能通过db.[documentName]得到 db.getCollection(documentName) 示例> use db-text
switched to db db-text
> db.getCollection("db-text").text.insert({name:"zhangSan", age:20})
WriteResult({ "nInserted" : 1 })
> show collections
db-text.text
> show dbs
admin 0.000GB
config 0.000GB
db-text 0.000GB
foobar 0.000GB
local 0.000GB
> db.getCollection("db-collection").insert({name:"lisi", age:25})
WriteResult({ "nInserted" : 1 })
> show collections
db-collection
db-text.text
>
+ - 直接执行js代码> function insert(object) {
... db.getCollection("db-text").text.insert(object)
... }
> insert({age:32})
> db.getCollection("db-text").text.find()
{ "_id" : ObjectId("5ab9e40678f483849a9c43f5"), "name" : "zhangSan", "age" : 20 }
{ "_id" : ObjectId("5ab9e62578f483849a9c43f7"), "age" : 32 }
>
> db.eval("return 'mongodb'")
WARNING: db.eval is deprecated
mongodb
+ - bson扩充的数据类型 null 表示空或不存在的字段 布尔 true或false 32位和64整数 Shell中不支持,需要其他高级语言的驱动来完成 64位浮点 Shell中使用的数字其实全是这种类型{x:3.1415} UTF-8 其实就是字符串类型 对象ID 内置默认ID对象{_id:ObjectId()} 日期 {x:new Date()} 正则 {x:/uspcat/i} Javascript代码块 {x:function() {...}} undefined 为定义类型,他和null不是一个类型 数组 {gps::[20,56]} 内嵌文档 {x:{name:"uspcat"}} 二进制 任意字节的字符串shell中无法使用 document + - 插入 + - 批量插入> db.persons.insert([{name:"22"},{name:"33"}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 2,
"nUpserted" : 0,
"nMatched" : 0,
"nModified" : 0,
"nRemoved" : 0,
"upserted" : [ ]
})
> db.persons.find()
{ "_id" : ObjectId("5ab9d67278f483849a9c43f4"), "name" : "uspcat" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f8"), "name" : "22" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f9"), "name" : "33" }
>
v1.12.4已经可以这样批量插入数据
12年的老版本,会插入一条如下记录
{"_id":ObjectId("xxx"), "0":{"name":"22"},"1":{"name":"33"}}
> for(var i = 0; i < 10; i++) {
... db.persons.insert({name: i})
... }
WriteResult({ "nInserted" : 1 })
> db.persons.find()
{ "_id" : ObjectId("5ab9d67278f483849a9c43f4"), "name" : "uspcat" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f8"), "name" : "22" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f9"), "name" : "33" }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fa"), "name" : 0 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fb"), "name" : 1 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fc"), "name" : 2 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fd"), "name" : 3 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fe"), "name" : 4 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43ff"), "name" : 5 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4400"), "name" : 6 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4401"), "name" : 7 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4402"), "name" : 8 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4403"), "name" : 9 }
>
save操作 + - 保存相同的id + - insert会报错> db.persons.insert({_id:"001",name:"zhangsan"})
WriteResult({ "nInserted" : 1 })
> db.persons.insert({_id:"001",name:"lisi"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: foobar.persons index: _id_ dup key: { : \"001\" }"
}
})
> db.persons.find()
{ "_id" : ObjectId("5ab9d67278f483849a9c43f4"), "name" : "uspcat" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f8"), "name" : "22" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f9"), "name" : "33" }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fa"), "name" : 0 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fb"), "name" : 1 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fc"), "name" : 2 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fd"), "name" : 3 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fe"), "name" : 4 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43ff"), "name" : 5 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4400"), "name" : 6 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4401"), "name" : 7 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4402"), "name" : 8 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4403"), "name" : 9 }
{ "_id" : "001", "name" : "zhangsan" }
save会更新> db.persons.save({_id:"001", name:"lisi"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : ObjectId("5ab9d67278f483849a9c43f4"), "name" : "uspcat" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f8"), "name" : "22" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f9"), "name" : "33" }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fa"), "name" : 0 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fb"), "name" : 1 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fc"), "name" : 2 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fd"), "name" : 3 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fe"), "name" : 4 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43ff"), "name" : 5 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4400"), "name" : 6 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4401"), "name" : 7 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4402"), "name" : 8 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4403"), "name" : 9 }
{ "_id" : "001", "name" : "lisi" }
>
+ - 删除 删除集合所有数据 db.[documentName].remove() db.persons.remove() 根据条件删除 db.[documentName].remove({}) db.persons.remove({_id:"001"}) 技巧删除一个数据量十分庞大的集合(比如TB级)
直接drop()删除该集合,并重建索引比直接remove()效率高很多
更新 语法 db.[documentName].update({查询器},{修改器}, insertOrUpdate, batchUpdate) 查询器 修改器 + - insertOrUpdate boolean,是否执行insert 查询器查出数据就执行update,否则执行insert db.[documentName].update({查询器},{修改器}, true) + - 示例> db.persons.update({_id:4},{name:"name4"})
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0 })
> db.persons.find()
{ "_id" : ObjectId("5ab9d67278f483849a9c43f4"), "name" : "uspcat" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f8"), "name" : "22" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f9"), "name" : "33" }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fa"), "name" : 0 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fb"), "name" : 1 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fc"), "name" : 2 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fd"), "name" : 3 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fe"), "name" : 4 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43ff"), "name" : 5 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4400"), "name" : 6 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4401"), "name" : 7 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4402"), "name" : 8 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4403"), "name" : 9 }
{ "_id" : "001", "name" : "lisi" }
> db.persons.update({_id:4},{name:"name4"}, true)
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 4 })
> db.persons.find()
{ "_id" : ObjectId("5ab9d67278f483849a9c43f4"), "name" : "uspcat" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f8"), "name" : "22" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f9"), "name" : "33" }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fa"), "name" : 0 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fb"), "name" : 1 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fc"), "name" : 2 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fd"), "name" : 3 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fe"), "name" : 4 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43ff"), "name" : 5 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4400"), "name" : 6 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4401"), "name" : 7 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4402"), "name" : 8 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4403"), "name" : 9 }
{ "_id" : "001", "name" : "lisi" }
{ "_id" : 4, "name" : "name4" }
>
batchUpdate boolean,是否批量更新 默认只修改匹配的第一条记录 db.[documentName].update({查询器},{修改器}, false, true) 示例 + - 只更新第一条> db.persons.find()
{ "_id" : "001", "name" : "lisi" }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({name:"lisi"},{name:"wangwu"})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "wangwu" }
{ "_id" : "002", "name" : "lisi" }
+ - 更新所有符合条件的记录 不加$set> db.persons.find()
{ "_id" : "001", "name" : "lisi" }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({name:"lisi"},{name:"wangwu"}, false, true)
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 9,
"errmsg" : "multi update only works with $ operators"
}
})
加$set> db.persons.update({name:"lisi"},{$set:{name:"wangwu"}}, false, true)
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
> db.persons.find()
{ "_id" : "001", "name" : "wangwu" }
{ "_id" : "002", "name" : "wangwu" }
>
强硬的文档替换式更新操作 db.[documentName].update({查询器},{修改器}) 用新的文档完全替换老的文档 + - 主键冲突时报错并回滚操作> db.persons.update({name:"uspcat"},{_id:"001",age:23})
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 66,
"errmsg" : "After applying the update, the (immutable) field '_id' was found to have been altered to _id: \"001\""
}
})
> db.persons.find()
{ "_id" : ObjectId("5ab9d67278f483849a9c43f4"), "name" : "uspcat" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f8"), "name" : "22" }
{ "_id" : ObjectId("5ab9f34578f483849a9c43f9"), "name" : "33" }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fa"), "name" : 0 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fb"), "name" : 1 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fc"), "name" : 2 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fd"), "name" : 3 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43fe"), "name" : 4 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c43ff"), "name" : 5 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4400"), "name" : 6 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4401"), "name" : 7 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4402"), "name" : 8 }
{ "_id" : ObjectId("5ab9f55a78f483849a9c4403"), "name" : 9 }
{ "_id" : "001", "name" : "lisi" }
>
修改器完成局部更新$set
语法 {$set:{field: value}} 案例 {$set:{name: "uspcat"}} + - 示例指定一个KV对,如果键存在就修改,不存在就添加
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan" }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({_id: "001"},{$set:{age: 20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "age" : 20 }
{ "_id" : "002", "name" : "lisi" }
$inc
语法 {$inc:{field: value}} 案例 {$inc:{"count": 1}} + - 示例只使用数字类型,为指定键对应的数字类型的值进行加减操作
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "age" : 20 }
{ "_id" : "002", "name" : "lisi" }
>
>
> db.persons.update({_id: "001"}, {$inc:{age: 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "age" : 21 }
{ "_id" : "002", "name" : "lisi" }
>
$unset
语法 {$unset:{field: 1}} 案例 {$unset:{"name": 1}} + - 示例删除指定的键
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "age" : 21 }
{ "_id" : "002", "name" : "lisi" }
>
>
> db.persons.update({_id: "001"}, {$unset: {age: 1} })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan" }
{ "_id" : "002", "name" : "lisi" }
>
$push
语法 {$push:{field: value}} 案例 {$push:{books: "JS"}} 说明 指定的键是数组,追加新的值 指定的键不是数组,中断当前操作 指定的键不存在,创建数组类型的键值对 + - 示例> db.persons.find()
{ "_id" : "001", "name" : "zhangsan" }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({_id: "001"}, {$push: {books: "js"} })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.update({_id: "001"}, {$push: {books: "extjs"} })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "js", "extjs" ] }
{ "_id" : "002", "name" : "lisi" }
>
$pushAll
语法 {$pushAll:{field: array}} 案例 {$pushAll:{books: ["extjs", "js"]}} 用法和$push相信,但可以批量添加数组数据 v3.6.3已经废弃了此功能,由$push代替 + - 示例> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "js", "extjs" ] }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({_id: "001"}, {$pushAll: {favors: ["run", "swim", "play"]} })
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 9,
"errmsg" : "Unknown modifier: $pushAll"
}
})
>
> db.persons.update({_id: "001"}, {$push: {favors: ["run", "swim", "play"]} })
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "js", "extjs" ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
$addToSet
语法 {$addToSet: {field: value}} 安例 {$addToSet: {books: "js"}} 目标数组存在,则不操作;不存在则加进去 + - 示例> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "js", "extjs" ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({_id: "001"}, {$addToSet: {books: "java"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "js", "extjs", "java" ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
$pop
语法 {$pop:{field: value}} 案例 从指定数组删除一个值 {$pop:{name: 1}} 删除最后一个值 {$pop:{name: -1}} 删除第一个值 + - 示例> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "js", "extjs", "java" ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({_id: "001"}, {$pop: {books: 1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "js", "extjs" ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({_id: "001"}, {$pop: {books: -1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "extjs" ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
$pull
语法 {$pull:{field: value}} 案例 {$pull:{"book": "js"}} + - 示例删除一个被指定的值
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ "extjs" ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
> db.persons.update({_id: "001"}, {$pull: {books: "extjs"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find()
{ "_id" : "001", "name" : "zhangsan", "books" : [ ], "favors" : [ [ "run", "swim", "play" ] ] }
{ "_id" : "002", "name" : "lisi" }
$pullAll
语法 {$pullAll:{field: array}} 案例 {$pullAll:{"book": ["js", "java"]}} 批量删除多个指定的值$
语法
{$push:{field: value}}案例
{$push:{books: "js"}}数组定位器:如果数组有多个值,只想对其中一部分操作
示例
{name: "YFC", age: 27, books: [{type: "js", name: "extjs4"}, {type: "js", name: "jquery"}, {type: "db", name: "mongodb"} ]}
把type为js的文档增加一个相同的作者author是uspcat
db.persons.update({"books.type":"js"}, {$set: {"books.$.author": "uspcat"}})
$addToSet与$each结合
完成批量数组更新
db.persons.update({_id: 1000}, {$addToSet: {books: {$each: ["js", "db"]}}}) $each会循环后面的数组,把每一个数组进行$addToSet操作runCommand函数和
findAndModify函数
runCommand 可以执行mongoDB中的特殊函数 findAndModify 就是特殊函数之一 用于返回update或remove后的文档 + - 格式runCommand({
"findAndModify": "processes",
query:{查询器},
sort{排序},
new:true, //是否返回更新前的文档
update: {更新器},
remove: true
}).value
+ - 示例ps = db.runCommand({
"findAndModify": "persons",
"query": {"name": "zhangsan"},
"update": {"$set": {"email": "abc@sohu.com"}},
"new": true
}).value
do_something(ps)
+ - 网例http://www.cppblog.com/byc/archive/2011/07/15/151063.aspx
> db.persons.find({age:{$gte:25, $lte: 27}}, {_id:0, name:1, age:1, country:1})
{ "name" : "jim", "age" : 25, "country" : "USA" }
{ "name" : "tom", "age" : 25, "country" : "USA" }
{ "name" : "lili", "age" : 26, "country" : "USA" }
{ "name" : "zhangsan", "age" : 27, "country" : "China" }
{ "name" : "lisi", "age" : 26, "country" : "China" }
{ "name" : "wangwu", "age" : 27, "country" : "China" }
{ "name" : "zhaoliu", "age" : 27, "country" : "China" }
{ "name" : "piaoyingjun", "age" : 26, "country" : "Korea" }
{ "name" : "lizhenxian", "age" : 27, "country" : "Korea" }
$gt >$gt4 >= $ne != {age: {$ne: 26} } 示例> db.persons.find({age:{$gte:25, $lte: 27}, country: {$ne: "Korea"}}, {_id:0, name:1, age:1, country:1})
{ "name" : "jim", "age" : 25, "country" : "USA" }
{ "name" : "tom", "age" : 25, "country" : "USA" }
{ "name" : "lili", "age" : 26, "country" : "USA" }
{ "name" : "zhangsan", "age" : 27, "country" : "China" }
{ "name" : "lisi", "age" : 26, "country" : "China" }
{ "name" : "wangwu", "age" : 27, "country" : "China" }
{ "name" : "zhaoliu", "age" : 27, "country" : "China" }
包含或不包含 + - $in查询国籍是中国或美国的人员
> db.persons.find({country: {$in: ["USA", "China"]}}, {_id:0, name:1, age:1, country:1})
{ "name" : "jim", "age" : 25, "country" : "USA" }
{ "name" : "tom", "age" : 25, "country" : "USA" }
{ "name" : "lili", "age" : 26, "country" : "USA" }
{ "name" : "zhangsan", "age" : 27, "country" : "China" }
{ "name" : "lisi", "age" : 26, "country" : "China" }
{ "name" : "wangwu", "age" : 27, "country" : "China" }
{ "name" : "zhaoliu", "age" : 27, "country" : "China" }
+ - $nin查询国籍不是中国或美国的人员
> db.persons.find({country: {$nin: ["USA", "China"]}}, {_id:0, name:1, age:1, country:1})
{ "name" : "piaoyingjun", "age" : 26, "country" : "Korea" }
{ "name" : "lizhenxian", "age" : 27, "country" : "Korea" }
{ "name" : "lixiaoli", "age" : 21, "country" : "Korea" }
{ "name" : "zhangsuying", "age" : 22, "country" : "Korea" }
仅作用于数组,而不使用于其他对象 + - $or查询$or
查询语文成绩大于85或者英语成绩大于90的学生
> db.persons.find({$or: [{c: {$gt:85}}, {e: {$gt: 90}}]}, {_id:0, name:1, c:1, e:1})
{ "name" : "jim", "c" : 89, "e" : 87 }
{ "name" : "tom", "c" : 75, "e" : 97 }
{ "name" : "lili", "c" : 75, "e" : 97 }
{ "name" : "zhangsan", "c" : 89, "e" : 67 }
{ "name" : "wangwu", "c" : 45, "e" : 99 }
{ "name" : "zhaoliu", "c" : 99, "e" : 97 }
null + - 构造数据把中国国籍的学生上增加新的键sex
> db.persons.find({country: "China"}, {_id:0, name: 1, country:1})
{ "name" : "zhangsan", "country" : "China" }
{ "name" : "lisi", "country" : "China" }
{ "name" : "wangwu", "country" : "China" }
{ "name" : "zhaoliu", "country" : "China" }
> db.persons.update({country: "China"}, {$set:{sex: "m"}}, false, true)
WriteResult({ "nMatched" : 4, "nUpserted" : 0, "nModified" : 4 })
> db.persons.find({country: "China"}, {_id:0, name: 1, country:1, sex:1})
{ "name" : "zhangsan", "country" : "China", "sex" : "m" }
{ "name" : "lisi", "country" : "China", "sex" : "m" }
{ "name" : "wangwu", "country" : "China", "sex" : "m" }
{ "name" : "zhaoliu", "country" : "China", "sex" : "m" }
+ - 实施查询查询sex等于null的学生
> db.persons.find({sex: {$in: [null]}}, {_id:0, name:1, country:1, sex:1})
{ "name" : "jim", "country" : "USA" }
{ "name" : "tom", "country" : "USA" }
{ "name" : "lili", "country" : "USA" }
{ "name" : "piaoyingjun", "country" : "Korea" }
{ "name" : "lizhenxian", "country" : "Korea" }
{ "name" : "lixiaoli", "country" : "Korea" }
{ "name" : "zhangsuying", "country" : "Korea" }
正则查询 + - 示例查询名字中有"li"的学生
> db.persons.find({name: /li/i}, {_id:0, name:1, country:1})
{ "name" : "lili", "country" : "USA" }
{ "name" : "lisi", "country" : "China" }
{ "name" : "zhaoliu", "country" : "China" }
{ "name" : "lizhenxian", "country" : "Korea" }
{ "name" : "lixiaoli", "country" : "Korea" }
$not取反 + - 示例查询名字中没有"li"的学生
> db.persons.find({name: {$not: /li/i} }, {_id:0, name:1, country:1})
{ "name" : "jim", "country" : "USA" }
{ "name" : "tom", "country" : "USA" }
{ "name" : "zhangsan", "country" : "China" }
{ "name" : "wangwu", "country" : "China" }
{ "name" : "piaoyingjun", "country" : "Korea" }
{ "name" : "zhangsuying", "country" : "Korea" }
$not与$nin区别 $not可以用在任何地方 $nin只能用在集合 数组查询 + - $all查询喜欢MONGODB和JS的学生
> db.persons.find({books: {$all : ["JS", "MONGODB"]}}, {_id:0, name:1, books:1})
{ "name" : "jim", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ] }
{ "name" : "lili", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
{ "name" : "zhangsan", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "name" : "lisi", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "name" : "wangwu", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "name" : "piaoyingjun", "books" : [ "JS", "C#", "EXTJS", "MONGODB" ] }
{ "name" : "lizhenxian", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "name" : "lixiaoli", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ] }
{ "name" : "zhangsuying", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
>
+ - index查询第二本书是JAVA的学生
> db.persons.find({"books.1": "JAVA"}, {_id:0, name:1, books:1})
{ "name" : "tom", "books" : [ "PHP", "JAVA", "EXTJS", "C++" ] }
{ "name" : "lili", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
{ "name" : "zhangsan", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "name" : "wangwu", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "name" : "zhaoliu", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }
{ "name" : "lizhenxian", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "name" : "lixiaoli", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ] }
{ "name" : "zhangsuying", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
+ - $size + - 指定数组长度查询喜欢的书籍数量是4本的学生
> db.persons.find({books: {$size: 4}}, {_id:0, name:1, books:1})
{ "name" : "jim", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ] }
{ "name" : "tom", "books" : [ "PHP", "JAVA", "EXTJS", "C++" ] }
{ "name" : "lili", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
{ "name" : "zhangsan", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "name" : "lisi", "books" : [ "JS", "C#", "PHP", "MONGODB" ] }
{ "name" : "wangwu", "books" : [ "JS", "JAVA", "C++", "MONGODB" ] }
{ "name" : "zhaoliu", "books" : [ "JS", "JAVA", "EXTJS", "PHP" ] }
{ "name" : "piaoyingjun", "books" : [ "JS", "C#", "EXTJS", "MONGODB" ] }
{ "name" : "lizhenxian", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ] }
{ "name" : "lixiaoli", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ] }
{ "name" : "zhangsuying", "books" : [ "JS", "JAVA", "C#", "MONGODB" ] }
不能与比较查询一起使用 + - 添加计算字段sizexdb.persons.update({}, {$set:{sizex: 4}}, false, true)
+ - 改变书籍的更新方式每次增加书籍的时候sizex加1
db.persons.update({country: "China"}, {$push: {books: "ORACLE"}, $inc: {sizex:1}}, false, true)
+ - 对sizex使用比较条件> db.persons.find({sizex: {$gt: 3}}, {_id:0, name:1, books:1, sizex:1})
{ "name" : "jim", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ], "sizex" : 4 }
{ "name" : "tom", "books" : [ "PHP", "JAVA", "EXTJS", "C++" ], "sizex" : 4 }
{ "name" : "lili", "books" : [ "JS", "JAVA", "C#", "MONGODB" ], "sizex" : 4 }
{ "name" : "zhangsan", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB", "ORACLE" ], "sizex" : 5 }
{ "name" : "lisi", "books" : [ "JS", "C#", "PHP", "MONGODB", "ORACLE" ], "sizex" : 5 }
{ "name" : "wangwu", "books" : [ "JS", "JAVA", "C++", "MONGODB", "ORACLE" ], "sizex" : 5 }
{ "name" : "zhaoliu", "books" : [ "JS", "JAVA", "EXTJS", "PHP", "ORACLE" ], "sizex" : 5 }
{ "name" : "piaoyingjun", "books" : [ "JS", "C#", "EXTJS", "MONGODB" ], "sizex" : 4 }
{ "name" : "lizhenxian", "books" : [ "JS", "JAVA", "EXTJS", "MONGODB" ], "sizex" : 4 }
{ "name" : "lixiaoli", "books" : [ "JS", "JAVA", "PHP", "MONGODB" ], "sizex" : 4 }
{ "name" : "zhangsuying", "books" : [ "JS", "JAVA", "C#", "MONGODB" ], "sizex" : 4 }
+ - shell查询查询jim喜欢的书的数量
> var p = db.persons.find({name: "jim"})
> p
{ "_id" : ObjectId("5abae30e78f483849a9c4404"), "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ], "sizex" : 4 }
> while(p.hasNext()) {
... obj = p.next();
... print(obj.books.length)
... }
> p.books
>
$slice 返回文档中指定数组的内部值 + - 查询jim书架中第2-4本书> db.persons.find({name: "jim"}, {_id:0, name:1, books: 1})
{ "name" : "jim", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ] }
> db.persons.find({name: "jim"}, {books: {$slice: [1,3]}})
{ "_id" : ObjectId("5abae30e78f483849a9c4404"), "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "C++", "EXTJS", "MONGODB" ], "sizex" : 4 }
> db.persons.find({name: "jim"}, {_id:0, books: {$slice: [1,3]}})
{ "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "C++", "EXTJS", "MONGODB" ], "sizex" : 4 }
+ - 查询出最后一本书> db.persons.find({name: "jim"}, {_id:0, books:1} )
{ "books" : [ "JS", "C++", "EXTJS", "MONGODB" ] }
> db.persons.find({name: "jim"}, {_id:0, books: {$slice: -1}})
{ "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "MONGODB" ], "sizex" : 4 }
文档查询 + - 数据准备> var jim = [{
... schoolName: "K",
... score: "A"
... }, {
... schoolName: "L",
... score: "B"
... }, {
... schoolName: "J",
... score: "A+"
... }]
> db.persons.update({name: "jim"}, {$set: {school:jim}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.persons.find({name:"jim"})
{ "_id" : ObjectId("5abae30e78f483849a9c4404"), "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ], "sizex" : 4, "school" : [ { "schoolName" : "K", "score" : "A" }, { "schoolName" : "L", "score" : "B" }, { "schoolName" : "J", "score" : "A+" } ] }
>
查询出在K学校上过学的学生 + - 绝对匹配存在问题
顺序 查询条件总要带score> db.persons.find({school: {schoolName: "K", score: "A"}}, {_id:0, name:1, school:1})
{ "name" : "jim", "school" : [ { "schoolName" : "K", "score" : "A" }, { "schoolName" : "L", "score" : "B" }, { "schoolName" : "J", "score" : "A+" } ] }
> db.persons.find({school: {score: "A", schoolName: "K"}}, {_id:0, name:1, school:1})
>//schoolName与score顺序切换后,没有查询结果
> db.persons.find({school: {schoolName: "K"}}, {_id:0, name:1, school:1})
>//查询条件没有score,就没有结果
+ - 解决顺序问题用对象"."定位属性
> db.persons.find({"school.score": "A", "school.schoolName": "K"}, {_id:0, name:1, school:1})
{ "name" : "jim", "school" : [ { "schoolName" : "K", "score" : "A" }, { "schoolName" : "L", "score" : "B" }, { "schoolName" : "J", "score" : "A+" } ] }
>
> db.persons.find({"school.schoolName": "K"}, {_id:0, name:1, school:1})
{ "name" : "jim", "school" : [ { "schoolName" : "K", "score" : "A" }, { "schoolName" : "L", "score" : "B" }, { "schoolName" : "J", "score" : "A+" } ] }
>//只有一个条件,不加score也有查询结果,不是K学校的信息也在查询结果中
+ - "换行"匹配问题查询在J学校分数为A的学生信息
> db.persons.find({"school.score": "A", "school.schoolName": "J"}, {_id:0, name:1, school:1})
{ "name" : "jim", "school" : [ { "schoolName" : "K", "score" : "A" }, { "schoolName" : "L", "score" : "B" }, { "schoolName" : "J", "score" : "A+" } ] }
>
事实上不存在J学校且分数为A的学生信息
查询结构匹配了”不同行“的学校学分信息
学校条件和学分条件逐个匹配造成的
+ - 正解$elemMatch
> db.persons.find({school: {$elemMatch:{schoolName: "K", score: "A"}}}, {_id:0, name:1, school:1})
{ "name" : "jim", "school" : [ { "schoolName" : "K", "score" : "A" }, { "schoolName" : "L", "score" : "B" }, { "schoolName" : "J", "score" : "A+" } ] }
> db.persons.find({school: {$elemMatch:{schoolName: "J", score: "A"}}}, {_id:0, name:1, school:1})
>//此时不会换行匹配
+ - $where查询年龄大于22,喜欢看C++,在K上过学
$where适用在复杂查询时使用,万能
尽量避免使用$where,影响性能
db.persons.find({"$where":function() {
var books = this.books;
var school = this.school;
if(this.age > 22) {
var cpp = null;
for(var i = 0; i < books.length; i++) {
if(books[i] == "C++") {
cpp = books[i];
if(school) {
for(var j = 0; j < school.length; j++) {
if(school[j].schoolName == "K") {
return true;
}
}
break;
}
}
}
}
}})
{ "_id" : ObjectId("5abae30e78f483849a9c4404"), "name" : "jim", "age" : 25, "email" : "75431457@qq.com", "c" : 89, "m" : 96, "e" : 87, "country" : "USA", "books" : [ "JS", "C++", "EXTJS", "MONGODB" ], "sizex" : 4, "school" : [ { "schoolName" : "K", "score" : "A" }, { "schoolName" : "L", "score" : "B" }, { "schoolName" : "J", "score" : "A+" } ] }
>
分页与排序 limit 返回指定的数据条数 + - 示例> db.persons.find({}, {_id:0, name:1})
{ "name" : "jim" }
{ "name" : "tom" }
{ "name" : "lili" }
{ "name" : "zhangsan" }
{ "name" : "lisi" }
{ "name" : "wangwu" }
{ "name" : "zhaoliu" }
{ "name" : "piaoyingjun" }
{ "name" : "lizhenxian" }
{ "name" : "lixiaoli" }
{ "name" : "zhangsuying" }
> db.persons.find({}, {_id:0, name:1}).limit(5)
{ "name" : "jim" }
{ "name" : "tom" }
{ "name" : "lili" }
{ "name" : "zhangsan" }
{ "name" : "lisi" }
skip 返回指定数据的跨度 + - 示例> db.persons.find({}, {_id:0, name:1}).limit(5).skip(5)
{ "name" : "wangwu" }
{ "name" : "zhaoliu" }
{ "name" : "piaoyingjun" }
{ "name" : "lizhenxian" }
{ "name" : "lixiaoli" }
> db.persons.find({}, {_id:0, name:1}).skip(5).limit(5)
{ "name" : "wangwu" }
{ "name" : "zhaoliu" }
{ "name" : "piaoyingjun" }
{ "name" : "lizhenxian" }
{ "name" : "lixiaoli" }
>
sort + - 返回按年龄排序的数据[1, -1] 1 正序 -1 倒序 + - 排序优先级 最小值 null 数字 字符串 对象/文档 数组 二进制 对象ID 布尔 日期 时间戳-->正则-->最大值 + - 示例> db.persons.find({}, {_id:0, name:1, age:1}).sort({age: 1})
{ "name" : "lixiaoli", "age" : 21 }
{ "name" : "zhangsuying", "age" : 22 }
{ "name" : "jim", "age" : 25 }
{ "name" : "tom", "age" : 25 }
{ "name" : "lili", "age" : 26 }
{ "name" : "lisi", "age" : 26 }
{ "name" : "piaoyingjun", "age" : 26 }
{ "name" : "zhangsan", "age" : 27 }
{ "name" : "wangwu", "age" : 27 }
{ "name" : "zhaoliu", "age" : 27 }
{ "name" : "lizhenxian", "age" : 27 }
> db.persons.find({}, {_id:0, name:1, age:1}).sort({age: -1})
{ "name" : "zhangsan", "age" : 27 }
{ "name" : "wangwu", "age" : 27 }
{ "name" : "zhaoliu", "age" : 27 }
{ "name" : "lizhenxian", "age" : 27 }
{ "name" : "lili", "age" : 26 }
{ "name" : "lisi", "age" : 26 }
{ "name" : "piaoyingjun", "age" : 26 }
{ "name" : "jim", "age" : 25 }
{ "name" : "tom", "age" : 25 }
{ "name" : "zhangsuying", "age" : 22 }
{ "name" : "lixiaoli", "age" : 21 }
>
分页 + - 常用算法db.persons.find({}, {_id:0, name:1, age:1}).limit(5).skip(0)
db.persons.find({}, {_id:0, name:1, age:1}).limit(5).skip(5)
+ - 性能优化 TB级数据,常用算法分页性能较低 给每条记录增加创建时间属性 分页时以创建时间为条件db.persons.find({create_date: {$gt: 201703260058}}, {_id:0, name:1, age:1}).limit(5).skip(5)
软件开发的重点应当在便捷和精确查询,没有人翻一万页 游标 是单向的,只能读一遍 销毁条件 客户端发来信息 迭代完毕 默认超过10分钟未用,也会被清除 查询快照快照后,就会针对不变的集合进行游标运动
db.persons.find({$query:{name:"jim"}, $snapshot: true})
+ - 高级查询选项
$query $orderby $maxsan: integer 最多扫描的文档数 $min: doc查询开始 $max: doc查询结束 $hint: doc使用哪个索引 $explain: boolean 统计 $snapshot: boolean 一致快照+ - 为什么有时候需要快照
数据操作的过程,会把文档扩大,导致内存自动扩展 如果没有快照,内存扩展后,会把变大的内容放在后面 程序再按原来的索引操作,将不是原来对应的内容 + - 示例> var p = db.persons.find({}, {_id:0, name:1, age:1})
> while(p.hasNext()) {
... print(p.next().name)
... }
jim
tom
lili
zhangsan
lisi
wangwu
zhaoliu
piaoyingjun
lizhenxian
lixiaoli
zhangsuying
>
索引 索引详解 + - 数据准备> for(var i = 0; i < 200000; i++) {
... db.books.insert({number: i, name: i+"book"})
... }
+ - 检查查询性能var start = new Date()
db.books.find({number: 65871})
var end = new Date()
end - start
//128
+ - 为number建索引> db.books.ensureIndex({number:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
number:1,1是正序,-1是倒序
+ - 再次执行相同的查询var start = new Date()
db.books.find({number: 65871})
{ "_id" : ObjectId("5abb57f1dab431257e600800"), "number" : 65871, "name" : "65871book" }
var end = new Date()
end - start
10
>
性能提高10倍左右
索引的名称 默认为k_1或k_-1 k为字段名如number 1为正序 -1为倒序 + - 创建索引时指定索引名> db.books.ensureIndex({name: -1}, {name: "bookName"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
>
+ - 唯一索引> db.books.ensureIndex({name: 1}, {unique: true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4,
"ok" : 1
}
> db.books.find({name:"0book"})
{ "_id" : ObjectId("5abb57cddab431257e5f06b1"), "number" : 0, "name" : "0book" }
>
> db.books.insert({name: "0book"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error collection: foobar.books index: name_1 dup key: { : \"0book\" }"
}
})
>
+ - 去除重复值 创建唯一索引前,已经有重复数值 db.books.ensureIndex({name: -1}, {unique: true, dropDups: true}) hint强制查询使用指定的索引
索引必须已经存在,否则出错
> db.books.find({name: "12book"}).hint({name: 1})
{ "_id" : ObjectId("5abb57cddab431257e5f06bd"), "number" : 12, "name" : "12book" }
>
explain 查看本次查询使用的哪个索引和查询数据的状态信息 + - 示例> db.books.find({name: "12book"}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "foobar.books",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "12book"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"12book\", \"12book\"]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : -1
},
"indexName" : "bookName",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"12book\", \"12book\"]"
]
}
}
}
]
},
"serverInfo" : {
"host" : "WenderThinkPad",
"port" : 27017,
"version" : "3.6.3",
"gitVersion" : "9586e557d54ef70f9ca4b43c26892cd55257e1a5"
},
"ok" : 1
}
>
注意事项 创建索引时,1是正序,-1是倒序,不同的索引顺序适合不同的查询 索引会影响插入性能,适合查询多插入少的场景 复合索引要注意索引的先后顺序 所有键创建索引,不一定能提高性能 索引不是万能的 排序时,如果是超大数据量可以考虑创建索引 索引管理 system.indexes v3.6.3已经找不到 + - 后台执行db.books.ensureIndex({name: -1}, {background: true})
删除索引 + - 精确删除db.runCommand({dropIndexes: "books", index: "name_-1"})
> db.runCommand({dropIndexes: "books", index: "name_1"})
{ "nIndexesWas" : 4, "ok" : 1 }
> db.runCommand({dropIndexes: "books", index: "name_1"})
{
"nIndexesWas" : 3,
"ok" : 0,
"errmsg" : "index not found with name [name_1]",
"code" : 27,
"codeName" : "IndexNotFound"
}
+ - 批量删除db.runCommand({dropIndexes: "books", index: "*"})
空间索引 + - 数据准备var map = [{
"gis": {
"x": 185,
"y": 150
}
},{
"gis": {
"x": 70,
"y": 180
}
},{
"gis": {
"x": 75,
"y": 180
}
},{
"gis": {
"x": 185,
"y": 185
}
},{
"gis": {
"x": 65,
"y": 185
}
},{
"gis": {
"x": 50,
"y": 70
}
},{
"gis": {
"x": 50,
"y": 50
}
},{
"gis": {
"x": 60,
"y": 55
}
},{
"gis": {
"x": 65,
"y": 80
}
},{
"gis": {
"x": 55,
"y": 80
}
},{
"gis": {
"x": 0,
"y": 0
}
},{
"gis": {
"x": 0,
"y": 200
}
},{
"gis": {
"x": 200,
"y": 0
}
},{
"gis": {
"x": 200,
"y": 200
}
}]
for(var i = 0; i < map.length; i++) {
db.map.insert(map[i])
}
+ - 查询距离点(70,180)最近的3个点 添加2D索引默认建立一个[-180, 180]之间的2D索引
> db.map.ensureIndex({"gis":"2d"}, {min:-1, max:201})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
查询距点(70, 180)最近的3个点> db.map.find({"gis":{$near:[70,180]}}, {_id:0, gis:1}).limit(3)
{ "gis" : { "x" : 70, "y" : 180 } }
{ "gis" : { "x" : 75, "y" : 180 } }
{ "gis" : { "x" : 65, "y" : 185 } }
>
+ - 查询以点(50,50)和点(190,190)为对角线的正方形中的所有点> db.map.find({gis: {$within: {$box: [[50,50],[190,190]]}}}, {_id:0, gis:1})
{ "gis" : { "x" : 50, "y" : 50 } }
{ "gis" : { "x" : 60, "y" : 55 } }
{ "gis" : { "x" : 50, "y" : 70 } }
{ "gis" : { "x" : 55, "y" : 80 } }
{ "gis" : { "x" : 65, "y" : 80 } }
{ "gis" : { "x" : 65, "y" : 185 } }
{ "gis" : { "x" : 70, "y" : 180 } }
{ "gis" : { "x" : 75, "y" : 180 } }
{ "gis" : { "x" : 185, "y" : 150 } }
{ "gis" : { "x" : 185, "y" : 185 } }
>
+ - 查询以圆心为(56,80)半径为50的圆中的所有点> db.map.find({gis:{$within: {$center: [[56,80], 50]}}}, {_id:0, gis:1})
{ "gis" : { "x" : 50, "y" : 50 } }
{ "gis" : { "x" : 60, "y" : 55 } }
{ "gis" : { "x" : 50, "y" : 70 } }
{ "gis" : { "x" : 55, "y" : 80 } }
{ "gis" : { "x" : 65, "y" : 80 } }
>
count + distinct + group count查询persons中美国学生的人数
> db.persons.find({country: "USA"}).count()
3
distinct查询persons中都有哪些国家
db.runCommand(distinct: "集合名", key: "去重的键").values
> db.runCommand({distinct: "persons", key: "country"}).values
[ "USA", "China", "Korea" ]
>
group 语法db.runCommand({group: {
ns: 集合名字,
key:分组的键名称,
initial: 初始化累加器,
$reduce: 分组分解器,
condition: 条件,
finalize: 组完成器
}})
按照key分组 每组的每个文档都要执行$reduce方法 $reduce方法接收两个参数 组内本条记录 累加器数据 需求1 查出persons中每个国家学生数学成绩最好且在90分以上的学生信息 + - 代码db.runCommand({group:{
ns: "persons",
key: {"country": true},
initial: {m: 0},
$reduce: function(doc, prev) {
if(doc.m > prev.m) {
prev.m = doc.m;
prev.name = doc.name;
prev.country = doc.country;
}
},
condition: {m: {$gt: 90}}
}})
+ - 执行> db.runCommand({group:{
... ns: "persons",
... key: {"country": true},
... initial: {m: 0},
... $reduce: function(doc, prev) {
... if(doc.m > prev.m) {
... prev.m = doc.m;
... prev.name = doc.name;
... prev.country = doc.country;
... }
... },
... condition: {m: {$gt: 90}}
... }})
{
"retval" : [
{
"country" : "USA",
"m" : 96,
"name" : "jim"
},
{
"country" : "China",
"m" : 96,
"name" : "lisi"
}
],
"count" : NumberLong(3),
"keys" : NumberLong(2),
"ok" : 1
}
>
需求2 基于上一需求,把每个人信息链接起来写一个描述赋值到m上 + - 代码db.runCommand({group:{
ns: "persons",
key: {"country": true},
initial: {m: 0},
$reduce: function(doc, prev) {
if(doc.m > prev.m) {
prev.m = doc.m;
prev.name = doc.name;
prev.country = doc.country;
}
},
finalize: function(prev) {
prev.m = prev.name + " Math score " + prev.m
},
condition: {m: {$gt: 90}}
}})
+ - 执行> db.runCommand({group:{
... ns: "persons",
... key: {"country": true},
... initial: {m: 0},
... $reduce: function(doc, prev) {
... if(doc.m > prev.m) {
... prev.m = doc.m;
... prev.name = doc.name;
... prev.country = doc.country;
... }
... },
... finalize: function(prev) {
... prev.m = prev.name + " Math score " + prev.m
... },
... condition: {m: {$gt: 90}}
... }})
{
"retval" : [
{
"country" : "USA",
"m" : "jim Math score 96",
"name" : "jim"
},
{
"country" : "China",
"m" : "lisi Math score 96",
"name" : "lisi"
}
],
"count" : NumberLong(3),
"keys" : NumberLong(2),
"ok" : 1
}
>
用函数格式来分组 + - 数据准备db.persons.insert({
name: "USPCAT",
age: 27,
email: "223344@qq.com",
c: 89, m: 100, e: 67,
counTry: "China",
books: ["JS", "JAVA", "EXTJS", "MONGODB"]
})
集合中同时存在键country和counTry + - 错误结果> db.runCommand({group:{
... ns: "persons",
... key: {"country": true},
... initial: {m: 0},
... $reduce: function(doc, prev) {
... if(doc.m > prev.m) {
... prev.m = doc.m;
... prev.name = doc.name;
... prev.country = doc.country;
... }
... },
... finalize: function(prev) {
... prev.m = prev.name + " Math score " + prev.m
... },
... condition: {m: {$gt: 90}}
... }})
{
"retval" : [
{
"country" : "USA",
"m" : "jim Math score 96",
"name" : "jim"
},
{
"country" : "China",
"m" : "lisi Math score 96",
"name" : "lisi"
},
{
"country" : undefined,
"m" : "USPCAT Math score 100",
"name" : "USPCAT"
}
],
"count" : NumberLong(4),
"keys" : NumberLong(3),
"ok" : 1
}
>
正解 + - 代码db.runCommand({group:{
ns: "persons",
$keyf: function(doc) {
if(doc.counTry) {
return {country: doc.counTry}
} else {
return {country: doc.country}
}
},
initial: {m: 0},
$reduce: function(doc, prev) {
if(doc.m > prev.m) {
prev.m = doc.m;
prev.name = doc.name;
prev.country = doc.country;
if(doc.counTry) {
prev.country = doc.counTry
} else {
prev.country = doc.country
}
}
},
finalize: function(prev) {
prev.m = prev.name + " Math score " + prev.m
},
condition: {m: {$gt: 90}}
}})
+ - 执行> db.runCommand({group:{
... ns: "persons",
... $keyf: function(doc) {
... if(doc.counTry) {
... return {country: doc.counTry}
... } else {
... return {country: doc.country}
... }
... },
... initial: {m: 0},
... $reduce: function(doc, prev) {
... if(doc.m > prev.m) {
... prev.m = doc.m;
... prev.name = doc.name;
... prev.country = doc.country;
... if(doc.counTry) {
... prev.country = doc.counTry
... } else {
... prev.country = doc.country
... }
... }
... },
... finalize: function(prev) {
... prev.m = prev.name + " Math score " + prev.m
... },
... condition: {m: {$gt: 90}}
... }})
{
"retval" : [
{
"country" : "USA",
"m" : "jim Math score 96",
"name" : "jim"
},
{
"country" : "China",
"m" : "USPCAT Math score 100",
"name" : "USPCAT"
}
],
"count" : NumberLong(4),
"keys" : NumberLong(2),
"ok" : 1
}
>
数据库命令 命令执行器runCommand + - 执行删除表的操作> db.runCommand({drop: "tb1"})
{ "ns" : "foobar.tb1", "nIndexesWas" : 1, "ok" : 1 }
查询系统提供的命令 db.listCommands() http://localhost:28017/_commands 常用命令示例 + - 服务器版本号和主机操作系统> db.runCommand({buildInfo:1})
{
"version" : "3.6.3",
"gitVersion" : "9586e557d54ef70f9ca4b43c26892cd55257e1a5",
"targetMinOS" : "Windows 7/Windows Server 2008 R2",
"modules" : [ ],
"allocator" : "tcmalloc",
"javascriptEngine" : "mozjs",
"sysInfo" : "deprecated",
"versionArray" : [
3,
6,
3,
0
],
"openssl" : {
"running" : "OpenSSL 1.0.1u-fips 22 Sep 2016",
"compiled" : "OpenSSL 1.0.1u-fips 22 Sep 2016"
},
"buildEnvironment" : {
"distmod" : "2008plus-ssl",
"distarch" : "x86_64",
"cc" : "cl: Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24223 for x64",
"ccflags" : "/nologo /EHsc /W3 /wd4355 /wd4800 /wd4267 /wd4244 /wd4290 /wd4068 /wd4351 /wd4373 /we4013 /we4099 /we4930 /WX /Z7 /errorReport:none /MD /O2 /Oy- /bigobj /utf-8 /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Gw /Gy /Zc:inline",
"cxx" : "cl: Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24223 for x64",
"cxxflags" : "/TP",
"linkflags" : "/nologo /DEBUG /INCREMENTAL:NO /LARGEADDRESSAWARE /OPT:REF",
"target_arch" : "x86_64",
"target_os" : "windows"
},
"bits" : 64,
"debug" : false,
"maxBsonObjectSize" : 16777216,
"storageEngines" : [
"devnull",
"ephemeralForTest",
"mmapv1",
"wiredTiger"
],
"ok" : 1
}
>
+ - 集合的详细信息> db.runCommand({collStats: "persons"})
{
"ns" : "foobar.persons",
"size" : 2719,
"count" : 12,
"avgObjSize" : 226,
"storageSize" : 36864,
"capped" : false,
"wiredTiger" : {
"metadata" : {
"formatVersion" : 1
},
"creationString" : "access_pattern_hint=none,allocation_size=4KB,app_metadata=(formatVersion=1),assert=(commit_timestamp=none,read_timestamp=none),block_allocation=best,block_compressor=snappy,cache_resident=false,checksum=on,colgroups=,collator=,columns=,dictionary=0,encryption=(keyid=,name=),exclusive=false,extractor=,format=btree,huffman_key=,huffman_value=,ignore_in_memory_cache_size=false,immutable=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=4KB,key_format=q,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=64MB,log=(enabled=true),lsm=(auto_throttle=true,bloom=true,bloom_bit_count=16,bloom_config=,bloom_hash_count=8,bloom_oldest=false,chunk_count_limit=0,chunk_max=5GB,chunk_size=10MB,merge_custom=(prefix=,start_generation=0,suffix=),merge_max=15,merge_min=0),memory_page_max=10m,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false,prefix_compression_min=4,source=,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,type=file,value_format=u",
"type" : "file",
"uri" : "statistics:table:collection-9--9051181061076683562",
"LSM" : {
"bloom filter false positives" : 0,
"bloom filter hits" : 0,
"bloom filter misses" : 0,
"bloom filter pages evicted from cache" : 0,
"bloom filter pages read into cache" : 0,
"bloom filters in the LSM tree" : 0,
"chunks in the LSM tree" : 0,
"highest merge generation in the LSM tree" : 0,
"queries that could have benefited from a Bloom filter that did not exist" : 0,
"sleep for LSM checkpoint throttle" : 0,
"sleep for LSM merge throttle" : 0,
"total size of bloom filters" : 0
},
"block-manager" : {
"allocations requiring file extension" : 16,
"blocks allocated" : 120,
"blocks freed" : 29,
"checkpoint size" : 4096,
"file allocation unit size" : 4096,
"file bytes available for reuse" : 16384,
"file magic number" : 120897,
"file major version number" : 1,
"file size in bytes" : 36864,
"minor version number" : 0
},
"btree" : {
"btree checkpoint generation" : 2206,
"column-store fixed-size leaf pages" : 0,
"column-store internal pages" : 0,
"column-store variable-size RLE encoded values" : 0,
"column-store variable-size deleted values" : 0,
"column-store variable-size leaf pages" : 0,
"fixed-record size" : 0,
"maximum internal page key size" : 368,
"maximum internal page size" : 4096,
"maximum leaf page key size" : 2867,
"maximum leaf page size" : 32768,
"maximum leaf page value size" : 67108864,
"maximum tree depth" : 3,
"number of key/value pairs" : 0,
"overflow pages" : 0,
"pages rewritten by compaction" : 0,
"row-store internal pages" : 0,
"row-store leaf pages" : 0
},
"cache" : {
"bytes currently in the cache" : 7850,
"bytes read into cache" : 0,
"bytes written from cache" : 24497,
"checkpoint blocked page eviction" : 0,
"data source pages selected for eviction unable to be evicted" : 0,
"eviction walk passes of a file" : 0,
"eviction walk target pages histogram - 0-9" : 0,
"eviction walk target pages histogram - 10-31" : 0,
"eviction walk target pages histogram - 128 and higher" : 0,
"eviction walk target pages histogram - 32-63" : 0,
"eviction walk target pages histogram - 64-128" : 0,
"eviction walks abandoned" : 0,
"eviction walks gave up because they restarted their walk twice" : 0,
"eviction walks gave up because they saw too many pages and found no candidates" : 0,
"eviction walks gave up because they saw too many pages and found too few candidates" : 0,
"eviction walks reached end of tree" : 0,
"eviction walks started from root of tree" : 0,
"eviction walks started from saved location in tree" : 0,
"hazard pointer blocked page eviction" : 0,
"in-memory page passed criteria to be split" : 0,
"in-memory page splits" : 0,
"internal pages evicted" : 0,
"internal pages split during eviction" : 0,
"leaf pages split during eviction" : 0,
"modified pages evicted" : 1,
"overflow pages read into cache" : 0,
"page split during eviction deepened the tree" : 0,
"page written requiring lookaside records" : 0,
"pages read into cache" : 0,
"pages read into cache requiring lookaside entries" : 0,
"pages requested from the cache" : 276,
"pages seen by eviction walk" : 0,
"pages written from cache" : 60,
"pages written requiring in-memory restoration" : 0,
"tracked dirty bytes in the cache" : 0,
"unmodified pages evicted" : 0
},
"cache_walk" : {
"Average difference between current eviction generation when the page was last considered" : 0,
"Average on-disk page image size seen" : 0,
"Average time in cache for pages that have been visited by the eviction server" : 0,
"Average time in cache for pages that have not been visited by the eviction server" : 0,
"Clean pages currently in cache" : 0,
"Current eviction generation" : 0,
"Dirty pages currently in cache" : 0,
"Entries in the root page" : 0,
"Internal pages currently in cache" : 0,
"Leaf pages currently in cache" : 0,
"Maximum difference between current eviction generation when the page was last considered" : 0,
"Maximum page size seen" : 0,
"Minimum on-disk page image size seen" : 0,
"Number of pages never visited by eviction server" : 0,
"On-disk page image sizes smaller than a single allocation unit" : 0,
"Pages created in memory and never written" : 0,
"Pages currently queued for eviction" : 0,
"Pages that could not be queued for eviction" : 0,
"Refs skipped during cache traversal" : 0,
"Size of the root page" : 0,
"Total number of pages currently in cache" : 0
},
"compression" : {
"compressed pages read" : 0,
"compressed pages written" : 0,
"page written failed to compress" : 0,
"page written was too small to compress" : 60,
"raw compression call failed, additional data available" : 0,
"raw compression call failed, no additional data available" : 0,
"raw compression call succeeded" : 0
},
"cursor" : {
"bulk-loaded cursor-insert calls" : 0,
"create calls" : 5,
"cursor-insert key and value bytes inserted" : 8554,
"cursor-remove key bytes removed" : 16,
"cursor-update value bytes updated" : 0,
"insert calls" : 67,
"modify calls" : 1,
"next calls" : 1079,
"prev calls" : 1,
"remove calls" : 16,
"reserve calls" : 0,
"reset calls" : 297,
"restarted searches" : 0,
"search calls" : 90,
"search near calls" : 44,
"truncate calls" : 0,
"update calls" : 0
},
"reconciliation" : {
"dictionary matches" : 0,
"fast-path pages deleted" : 0,
"internal page key bytes discarded using suffix compression" : 0,
"internal page multi-block writes" : 0,
"internal-page overflow keys" : 0,
"leaf page key bytes discarded using prefix compression" : 0,
"leaf page multi-block writes" : 0,
"leaf-page overflow keys" : 0,
"maximum blocks required for a page" : 1,
"overflow values written" : 0,
"page checksum matches" : 0,
"page reconciliation calls" : 62,
"page reconciliation calls for eviction" : 1,
"pages deleted" : 2
},
"session" : {
"object compaction" : 0,
"open cursor count" : 1
},
"transaction" : {
"update conflicts" : 0
}
},
"nindexes" : 1,
"indexDetails" : {
"_id_" : {
"metadata" : {
"formatVersion" : 8,
"infoObj" : "{ \"v\" : 2, \"key\" : { \"_id\" : 1 }, \"name\" : \"_id_\", \"ns\" : \"foobar.persons\" }"
},
"creationString" : "access_pattern_hint=none,allocation_size=4KB,app_metadata=(formatVersion=8,infoObj={ \"v\" : 2, \"key\" : { \"_id\" : 1 }, \"name\" : \"_id_\", \"ns\" : \"foobar.persons\" }),assert=(commit_timestamp=none,read_timestamp=none),block_allocation=best,block_compressor=,cache_resident=false,checksum=on,colgroups=,collator=,columns=,dictionary=0,encryption=(keyid=,name=),exclusive=false,extractor=,format=btree,huffman_key=,huffman_value=,ignore_in_memory_cache_size=false,immutable=false,internal_item_max=0,internal_key_max=0,internal_key_truncate=true,internal_page_max=16k,key_format=u,key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=16k,leaf_value_max=0,log=(enabled=true),lsm=(auto_throttle=true,bloom=true,bloom_bit_count=16,bloom_config=,bloom_hash_count=8,bloom_oldest=false,chunk_count_limit=0,chunk_max=5GB,chunk_size=10MB,merge_custom=(prefix=,start_generation=0,suffix=),merge_max=15,merge_min=0),memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0,prefix_compression=true,prefix_compression_min=4,source=,split_deepen_min_child=0,split_deepen_per_child=0,split_pct=90,type=file,value_format=u",
"type" : "file",
"uri" : "statistics:table:index-10--9051181061076683562",
"LSM" : {
"bloom filter false positives" : 0,
"bloom filter hits" : 0,
"bloom filter misses" : 0,
"bloom filter pages evicted from cache" : 0,
"bloom filter pages read into cache" : 0,
"bloom filters in the LSM tree" : 0,
"chunks in the LSM tree" : 0,
"highest merge generation in the LSM tree" : 0,
"queries that could have benefited from a Bloom filter that did not exist" : 0,
"sleep for LSM checkpoint throttle" : 0,
"sleep for LSM merge throttle" : 0,
"total size of bloom filters" : 0
},
"block-manager" : {
"allocations requiring file extension" : 12,
"blocks allocated" : 44,
"blocks freed" : 10,
"checkpoint size" : 4096,
"file allocation unit size" : 4096,
"file bytes available for reuse" : 16384,
"file magic number" : 120897,
"file major version number" : 1,
"file size in bytes" : 36864,
"minor version number" : 0
},
"btree" : {
"btree checkpoint generation" : 2206,
"column-store fixed-size leaf pages" : 0,
"column-store internal pages" : 0,
"column-store variable-size RLE encoded values" : 0,
"column-store variable-size deleted values" : 0,
"column-store variable-size leaf pages" : 0,
"fixed-record size" : 0,
"maximum internal page key size" : 1474,
"maximum internal page size" : 16384,
"maximum leaf page key size" : 1474,
"maximum leaf page size" : 16384,
"maximum leaf page value size" : 7372,
"maximum tree depth" : 3,
"number of key/value pairs" : 0,
"overflow pages" : 0,
"pages rewritten by compaction" : 0,
"row-store internal pages" : 0,
"row-store leaf pages" : 0
},
"cache" : {
"bytes currently in the cache" : 3747,
"bytes read into cache" : 0,
"bytes written from cache" : 1858,
"checkpoint blocked page eviction" : 0,
"data source pages selected for eviction unable to be evicted" : 0,
"eviction walk passes of a file" : 0,
"eviction walk target pages histogram - 0-9" : 0,
"eviction walk target pages histogram - 10-31" : 0,
"eviction walk target pages histogram - 128 and higher" : 0,
"eviction walk target pages histogram - 32-63" : 0,
"eviction walk target pages histogram - 64-128" : 0,
"eviction walks abandoned" : 0,
"eviction walks gave up because they restarted their walk twice" : 0,
"eviction walks gave up because they saw too many pages and found no candidates" : 0,
"eviction walks gave up because they saw too many pages and found too few candidates" : 0,
"eviction walks reached end of tree" : 0,
"eviction walks started from root of tree" : 0,
"eviction walks started from saved location in tree" : 0,
"hazard pointer blocked page eviction" : 0,
"in-memory page passed criteria to be split" : 0,
"in-memory page splits" : 0,
"internal pages evicted" : 0,
"internal pages split during eviction" : 0,
"leaf pages split during eviction" : 0,
"modified pages evicted" : 0,
"overflow pages read into cache" : 0,
"page split during eviction deepened the tree" : 0,
"page written requiring lookaside records" : 0,
"pages read into cache" : 0,
"pages read into cache requiring lookaside entries" : 0,
"pages requested from the cache" : 67,
"pages seen by eviction walk" : 0,
"pages written from cache" : 22,
"pages written requiring in-memory restoration" : 0,
"tracked dirty bytes in the cache" : 0,
"unmodified pages evicted" : 0
},
"cache_walk" : {
"Average difference between current eviction generation when the page was last considered" : 0,
"Average on-disk page image size seen" : 0,
"Average time in cache for pages that have been visited by the eviction server" : 0,
"Average time in cache for pages that have not been visited by the eviction server" : 0,
"Clean pages currently in cache" : 0,
"Current eviction generation" : 0,
"Dirty pages currently in cache" : 0,
"Entries in the root page" : 0,
"Internal pages currently in cache" : 0,
"Leaf pages currently in cache" : 0,
"Maximum difference between current eviction generation when the page was last considered" : 0,
"Maximum page size seen" : 0,
"Minimum on-disk page image size seen" : 0,
"Number of pages never visited by eviction server" : 0,
"On-disk page image sizes smaller than a single allocation unit" : 0,
"Pages created in memory and never written" : 0,
"Pages currently queued for eviction" : 0,
"Pages that could not be queued for eviction" : 0,
"Refs skipped during cache traversal" : 0,
"Size of the root page" : 0,
"Total number of pages currently in cache" : 0
},
"compression" : {
"compressed pages read" : 0,
"compressed pages written" : 0,
"page written failed to compress" : 0,
"page written was too small to compress" : 0,
"raw compression call failed, additional data available" : 0,
"raw compression call failed, no additional data available" : 0,
"raw compression call succeeded" : 0
},
"cursor" : {
"bulk-loaded cursor-insert calls" : 0,
"create calls" : 3,
"cursor-insert key and value bytes inserted" : 430,
"cursor-remove key bytes removed" : 197,
"cursor-update value bytes updated" : 0,
"insert calls" : 29,
"modify calls" : 0,
"next calls" : 0,
"prev calls" : 0,
"remove calls" : 16,
"reserve calls" : 0,
"reset calls" : 66,
"restarted searches" : 0,
"search calls" : 22,
"search near calls" : 0,
"truncate calls" : 0,
"update calls" : 0
},
"reconciliation" : {
"dictionary matches" : 0,
"fast-path pages deleted" : 0,
"internal page key bytes discarded using suffix compression" : 0,
"internal page multi-block writes" : 0,
"internal-page overflow keys" : 0,
"leaf page key bytes discarded using prefix compression" : 621,
"leaf page multi-block writes" : 0,
"leaf-page overflow keys" : 0,
"maximum blocks required for a page" : 1,
"overflow values written" : 0,
"page checksum matches" : 0,
"page reconciliation calls" : 24,
"page reconciliation calls for eviction" : 0,
"pages deleted" : 2
},
"session" : {
"object compaction" : 0,
"open cursor count" : 1
},
"transaction" : {
"update conflicts" : 0
}
}
},
"totalIndexSize" : 36864,
"indexSizes" : {
"_id_" : 36864
},
"ok" : 1
}
>
+ - 操作本集合最后一次错误信息> db.runCommand({getLastError: "persons"})
{
"connectionId" : 7,
"n" : 0,
"syncMillis" : 0,
"writtenTo" : null,
"err" : null,
"ok" : 1
}
>
固定集合特性 特性 插入算法 删除末尾元素 新元素插在原先第一个元素之前 集合长度不变 默认没有索引,就算是_id也没有索引 不需要分配新的空间,插入速度非常快 顺序是确定的,查询速度非常快 适用场景 日志管理 创建 创建固定集合 长度100字节长,存储10个文档 + - 示例> db.createCollection("mycoll", {size:100, capped:true, max:10})
{ "ok" : 1 }
> db.mycoll.find()
> db.mycoll.insert({name:"zhangsan", age: 20})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan1", age: 21})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan2", age: 22})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan3", age: 23})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan4", age: 24})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan5", age: 25})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan6", age: 26})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan7", age: 27})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan8", age: 28})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({name:"zhangsan9", age: 29})
WriteResult({ "nInserted" : 1 })
> db.mycoll.find()
{ "_id" : ObjectId("5abc358bdab431257e621412"), "name" : "zhangsan6", "age" : 26 }
{ "_id" : ObjectId("5abc358bdab431257e621413"), "name" : "zhangsan7", "age" : 27 }
{ "_id" : ObjectId("5abc358bdab431257e621414"), "name" : "zhangsan8", "age" : 28 }
{ "_id" : ObjectId("5abc358bdab431257e621415"), "name" : "zhangsan9", "age" : 29 }
> db.mycoll.insert({_id: 0, name:"zhangsan", age: 20})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 1, name:"zhangsan1", age: 21})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 2, name:"zhangsan2", age: 22})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 3, name:"zhangsan3", age: 23})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 4, name:"zhangsan4", age: 24})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 5, name:"zhangsan5", age: 25})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 6, name:"zhangsan6", age: 26})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 7, name:"zhangsan7", age: 27})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 8, name:"zhangsan8", age: 28})
WriteResult({ "nInserted" : 1 })
> db.mycoll.insert({_id: 9, name:"zhangsan9", age: 29})
WriteResult({ "nInserted" : 1 })
> db.mycoll.find()
{ "_id" : 5, "name" : "zhangsan5", "age" : 25 }
{ "_id" : 6, "name" : "zhangsan6", "age" : 26 }
{ "_id" : 7, "name" : "zhangsan7", "age" : 27 }
{ "_id" : 8, "name" : "zhangsan8", "age" : 28 }
{ "_id" : 9, "name" : "zhangsan9", "age" : 29 }
没有超过100个字节,10个文档限制
转换集合 普通集合转换成固定集合 + - 示例> db.gencoll.insert({name:"zhangsan", age: 20})
WriteResult({ "nInserted" : 1 })
> db.gencoll.find()
{ "_id" : ObjectId("5abc3221dab431257e621402"), "name" : "zhangsan", "age" : 20 }
> db.runCommand({convertToCapped: "gencoll", size: 10})
{ "ok" : 1 }
> db.gencoll.find()
{ "_id" : ObjectId("5abc3221dab431257e621402"), "name" : "zhangsan", "age" : 20 }
>
反向排序 默认是插入顺序排序 + - 示例> db.mycoll.find()
{ "_id" : 5, "name" : "zhangsan5", "age" : 25 }
{ "_id" : 6, "name" : "zhangsan6", "age" : 26 }
{ "_id" : 7, "name" : "zhangsan7", "age" : 27 }
{ "_id" : 8, "name" : "zhangsan8", "age" : 28 }
{ "_id" : 9, "name" : "zhangsan9", "age" : 29 }
>
>
> db.mycoll.find().sort({$natural: -1})
{ "_id" : 9, "name" : "zhangsan9", "age" : 29 }
{ "_id" : 8, "name" : "zhangsan8", "age" : 28 }
{ "_id" : 7, "name" : "zhangsan7", "age" : 27 }
{ "_id" : 6, "name" : "zhangsan6", "age" : 26 }
{ "_id" : 5, "name" : "zhangsan5", "age" : 25 }
>
尾部游标 shell不支持 java、php等驱动支持 只能用在固定集合上的游标 没有结果时不自动销毁 一直等待结果的到来 GridFS文件系统 概念 系统自带的文件系统,用二进制存储文件 可以完成大型文件系统的绝大多数特性 工具 mongofiles.exe 使用 查看GridFS所有功能 cmd --> mongofiles 上传一个文件 mongofiles -d foobar -l "e:/abc.txt" put "abc.txt" 查看GridFS的文件存储状态 vue查看 集合查看 db.fs.chunks.find() db.fs.files.find() 查看文件内容 cmd --> mongofiles -d foobar get "abc.txt" 查看所有文件 cmd --> mongofiles -d foobar list 删除文件-vue操作 mongofiles -d foobar delete "abc.txt" 服务器端脚本 evaldb.eval("function(name) {return name)", "uspcat")
javascript存储 在服务器上保存js变量或者函数供全局调用 把变量加载到特殊集合system.js db.system.js.insert({_id:"name", value: "uspcat"}) + - 调用> db.eval("return name;")
WARNING: db.eval is deprecated
uspcat
> db.eval("return namex;")
WARNING: db.eval is deprecated
2018-03-29T08:59:41.129+0800 E QUERY [thread1] Error: {
"ok" : 0,
"errmsg" : "ReferenceError: namex is not defined :\n@:1:15\n",
"code" : 139,
"codeName" : "JSInterpreterFailure"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype.eval@src/mongo/shell/db.js:747:1
@(shell):1:1
>
system.js相当于数据库的存储过程,因为value不仅仅可以写变量,也可以写函数体,即javascript代码 启动配置 + - 启动项 mongod --help --dbpath 指定数据库的目录,默认在c:\data\db\ --port 服务器监听端口号,默认是27017 --fork 用守护进程的方式启动mongoDB --logpath 日志的输出路径,默认是控制台 --config 启动项用的配置文件路径mongodb.conf
dbpath=d:/mongodb/db
port=8888
mongod --config ./mongodb.conf
启动shell
mongo 127.0.0.1:8888
--auth 用安全认证方式启动数据库 + - 停止mongoDB服务 Ctrl + C 关闭数据库 admin数据库命令关闭数据库use admin
db.shutdownServer()
导出导入备份 + - 导出数据 中断其他操作 + - mongoexport -d 指明使用的库 -c 要导出的表 -csv 导出csv格式 -q 过滤导出 --type json csv tsv 示例1 把数据库foobar中的persons导出 mongoexport -d foobar -c persons -o D:/persons.json 示例2 导出其他主机数据库的文档 mongoexport --host xxxx --port 27017 .... + - 导入数据 中断其他操作 api http://cn.docs.mongodb.org/manual/reference/mongoimport/ 示例 mongoimport --db foobar --collection persons --file d:/persons.json 把persons.json文件导入集合 + - 备份 运动时备份 api http://cn.docs.mongodb.org/manual/reference/mongodump 示例 导出127.0.0.1服务27017下的foobar数据库 mongodump --host 127.0.0.1:27017 -d foobar -o d:/foobar 运行时恢复 api http://cn.docs.mongodb.org/manual/reference/mongorestore 示例 删除测试库,用刚才导出的备份文件恢复数据库 mongorestore --host 127.0.0.1:27017 -d foobar -directoryperdb d:/foobar/foobar 懒人备份 用拷贝文件的方式备份 fsync锁,数据修复 fsync锁 上锁 上锁可以将缓存池的数据全部进到数据库,在数据库备份时很有意义 db.runCommand({fsync:1, lock:1}); 解锁 db.currentOp() 数据修复突然断电时,由于mongodb的存储结构导致会产生垃圾数据,
在数据恢复以后,这些垃圾数据依然存在,
这是数据库提供的一个自我修复能力
db.repairDatabase()
用户管理,安全认证 v3.6.3这些命令不适用,改用db.createUser()... + - 用户管理 添加用户 为admin添加uspcat用户use admin
db.addUser("uspcat", "123");
为foobar添加fhb用户use foobar
db.addUser("fhb", "123");
启用用户db.auth("uspcat", "123");
+ - 安全认证 --auth mongod --dbpath d:\mongodb\db --rest --auth 非foobar的用户,不能操作foobar的数据库 不以admin启动mongodb mongo 127.0.0.1:27017 启用自己的用户才可以访问 db.auth("fhb", "123") 非admin数据库的用户不能使用数据库命令 db.auth("uspcat", "123") show dbs 删除用户 db.system.users.remove({user: "fhb"}); 云计算 + - 主从复制 数据库集群中要明确知道谁是主服务器,主服务器只有一台 从服务器要知道自己的数据源,也就是对应的主服务器 启动时可以没有从服务器,可以在运行时通过shell脚本为主服务器挂接从服务器 从服务器自动复制主服务器新创建或更新的数据库、集合 配置项 --master 确定主服务器 --slave和--source 控制从服务器 --only 从节点-->指定复制某个数据库 默认是复制全部数据库 如--only=foobar,则仅复制foobar --slavedelay 从节点-->设置主数据库同步数据的延迟(秒) --fastsync 从节点-->以主数据库的节点快照为节点启动从数据库 --autoresync 从节点-->如果不同步,则重新同步数据库新增从节点,默认从当前时间开始复制主数据库的数据
设置autoresync则从头复制数据
--oplogSize 主节点-->设置oplog的大小(主节点操作记录存储到local的oplog中) 示例 主 8888.confdbpath=D:/software/mongodb/01/8888 #主数据库地址
port=8888 #主数据库端口号
bind_ip=127.0.0.1 #主数据库所在服务器
master=true #是主服务器
8888startmongodb.bat mongod --config 8888.conf 8888shell.bat mongo 127.0.0.1:8888 从 7777.confdbpath=D:/software/mongodb/01/7777 #从数据库地址
port=7777 #从数据库端口号
bind_ip=127.0.0.1 #主数据库所在服务器
slave=true #是从服务器
source=127.0.0.1:8888 #主数据库服务器及端口,此配置项可在运行时用shell动态添加
7777startmongodb.bat mongod --config 7777.conf 7777shell.bat mongo 127.0.0.1:7777 shell动态添加删除从节点 从节点执行use local
db.sources.find()
从节点中关于主节点的信息全部存放在local的sources集合中 挂接主节点:操作前只留下从数据库服务 db.sources.insert({"host": "127.0.0.1:8888"}) 删除已经挂接的主节点:操作前只留下从数据库服务 db.sources.remove({"host": "127.0.0.1:8888"}) + - 副本集 + - 场景 初始状态 A 活跃 B 备份 C 备份 策略 如果各节点权重相同,则随机选择一个做活跃节点 A故障 A 宕机 B 活跃 C 备份 策略 A宕机,则从B、C中随机选择一个做活跃节点 A故障修复 A 备份 B 活跃 C 备份 策略 A故障修复后,自动做备份节点,而不是重做活跃节点 + - 设置 A A.confdbpath=D:/software/mongodb/02/1111
port=1111 #端口
bind_ip=127.0.0.1 #服务器地址
replSet=child/127.0.0.1:2222 #设定同伴
Ashell.batmongo 127.0.0.1:1111
Amongodb.bat mongod --config A.conf B B.confdbpath=D:/software/mongodb/02/2222
port=2222 #端口
bind_ip=127.0.0.1 #服务器地址
replSet=child/127.0.0.1:3333 #设定同伴
Bshell.batmongo 127.0.0.1:2222
Bmongodb.bat mongod --config B.conf C C.confdbpath=D:/software/mongodb/02/3333
port=3333 #端口
bind_ip=127.0.0.1 #服务器地址
replSet=child/127.0.0.1:1111 #设定同伴
Cshell.batmongo 127.0.0.1:3333
Cmongodb.bat mongod --config C.conf + - 初始化use admin
db.runCommand({"replSetInitiate":
{
"_id": "child",
"members": [{
"_id": 1,
"host", "127.0.0.1:1111"
},{
"_id": 2,
"host", "127.0.0.1:2222"
},{
"_id": 3,
"host", "127.0.0.1:3333"
}]
}
})
这里的"_id":"child"必须与配置文件中的"child"相同
+ - 查看状态 只有活跃点(即primary)才可以进行查询操作rs.status()
db.persons.insert({name:"123"}) db.persons.find() 备份点不能进行查询操作 db.persons.find()失败 + - 节点和初始化高级参数 standard 常规节点 参与投票有可能成为活跃节点 passive 副本节点 参与投票 不能成为活跃节点 arbiter 仲裁节点 参与投票 不复制节点 不能成功活跃节点 priority 0~1000之间 0副本节点 1~1000常规节点 arbiterOnly true仲裁节点 用法members":[{
"_id":1,
"host":"127.0.0.1:1111",
arbiterOnly:true
}]"
+ - 优先级相同时,仲裁规则 选择最新发生更新的节点 + - 读写分离 通常副本节点不能进行数据库读操作 读取密集型系统中读写分享十分必要 设置读写分离 slaveOkay:true + - oplog 被存储在本数据库local中 每一个文档保存一个节点操作 想故障恢复可以更彻底oplog可尽量设置大一些以保存更多的操作 改变oplog大小 主库 --master --oplogSize xxx 操作PRIMARY>use local
PRIMARY>db.oplog.rs.find()
分片 + - 什么时候用分片 磁盘空间不足 单个mongoDB服务器不能满足大量的插入操作 想通过把大数据放到内存中提高性能 + - 分片架构 用户 + - 配置服务器 可以有多台 启动2000端口 示例 configServer.confdbpath = D:\software\MongoDBDATA\08\config
port = 2000
bind_ip = 127.0.0.1
configServer.batmongod --config configServer.conf
+ - 路由服务器 监听配置服务器 路由服务器是1000的端口 监听配置服务器2000的端口 示例 router.batmongos --port 1000 --configdb 127.0.0.1:2000
routerShell.batmongo 127.0.0.1:1000/admin
+ - 片区Shard01 示例 shard01.confdbpath=D:\software\MongoDBDATA\08\0801
port=8081
bind_ip=127.0.0.1
shard01start.batmongod --config shard01.conf
shard01_8081.batmongo 127.0.0.1:8081/admin
+ - 片区Shard02 示例 shard02.confdbpath=D:\software\MongoDBDATA\08\0802
port=8082
bind_ip=127.0.0.1
shard02start.batmongod --config shard02.conf
shard02_8082.batmongo 127.0.0.1:8082/admin
+ - 分片步骤 创建一个配置服务器 创建路由服务器 连接配置服务器 路由服务器调用mongos命令 添加两个分片数据库 8081 8082 + - 利用路由为集群添加分片 允许本地访问 db.runCommand({addshard:"127.0.0.1:8081", allowLocal:true}) db.runCommand({addshard:"127.0.0.1:8082", allowLocal:true}) 切记之前不能使用任何数据库语句 打开数据库分片功能 为数据库foobar打开分片功能 db.runCommand({"enablesharding":"foobar"}) 对集合分片 db.runCommand({"shardcollection": "foobar", "key": {"_id": 1}}) 利用大数据量进行测试 + - 测试脚本function add(){
var i = 0;
for(;i<200000;i++){
db.persons.insert({"age":i+10,"name":"jim"})
}
}
function add2(){
var i = 0;
for(;i<200000;i++){
db.persons.insert({"age":12,"name":"tom"+i})
}
}
function add3(){
var i = 0;
for(;i<200000;i++){
db.persons.insert({"age":12,"name":"lili"+i})
}
}
//查看状态
db.printShardingStatus()
查看配置库对于分片服务器的配置存储 db.printShardingStatus() + - 查看集群对foobar的自动分片机制配置信息mongos>use config
mongos>show collections
mongos>db.shards.find()
{"_id": "shard0000", "host": "127.0.0.1:8081"}
{"_id": "shard0000", "host": "127.0.0.1:8082"}
mongos>db.mongos.find()