db的幫助文檔
輸入:db.help();
db.AddUser(username,password[, readOnly=false]) ?添加用戶 ?
db.auth(usrename,password) ? ? 設(shè)置數(shù)據(jù)庫連接驗(yàn)證 ?
db.cloneDataBase(fromhost) ? ? 從目標(biāo)服務(wù)器克隆一個數(shù)據(jù)庫 ?
db.commandHelp(name) ? ? ? ? ? returns the help for the command ?
db.copyDatabase(fromdb,todb,fromhost) ?復(fù)制數(shù)據(jù)庫fromdb---源數(shù)據(jù)庫名稱,todb---目標(biāo)數(shù)據(jù)庫名稱,fromhost---源數(shù)據(jù)庫服務(wù)器地址 ?
db.createCollection(name,{size:3333,capped:333,max:88888}) ?創(chuàng)建一個數(shù)據(jù)集,相當(dāng)于一個表 ?
db.currentOp() ? ? ? ? ? ? ? ? 取消當(dāng)前庫的當(dāng)前操作 ?
db.dropDataBase() ? ? ? ? ? ? ?刪除當(dāng)前數(shù)據(jù)庫 ?
db.eval(func,args) ? ? ? ? ? ? run code server-side ?
db.getCollection(cname) ? ? ? ?取得一個數(shù)據(jù)集合,同用法:db['cname'] or ?
db.getCollenctionNames() ? ? ? 取得所有數(shù)據(jù)集合的名稱列表 ?
db.getLastError() ? ? ? ? ? ? ?返回最后一個錯誤的提示消息 ?
db.getLastErrorObj() ? ? ? ? ? 返回最后一個錯誤的對象 ?
db.getMongo() ? ? ? ? ? ? ? ? ?取得當(dāng)前服務(wù)器的連接對象get the server ?
db.getMondo().setSlaveOk() ? ? allow this connection to read from then nonmaster membr of a replica pair ?
db.getName() ? ? ? ? ? ? ? ? ? 返回當(dāng)操作數(shù)據(jù)庫的名稱 ?
db.getPrevError() ? ? ? ? ? ? ?返回上一個錯誤對象 ?
db.getProfilingLevel() ? ? ? ? 獲取profile level ?
db.getReplicationInfo() ? ? ? ?獲得重復(fù)的數(shù)據(jù) ?
db.getSisterDB(name) ? ? ? ? ? get the db at the same server as this onew ?
db.killOp() ? ? ? ? ? ? ? ? ? ?停止(殺死)在當(dāng)前庫的當(dāng)前操作 ?
db.printCollectionStats() ? ? ?返回當(dāng)前庫的數(shù)據(jù)集狀態(tài) ?
db.printReplicationInfo() ? ? ? ?打印主數(shù)據(jù)庫的復(fù)制狀態(tài)信息 ?
db.printSlaveReplicationInfo() ? ? ? ?打印從數(shù)據(jù)庫的復(fù)制狀態(tài)信息 ?
db.printShardingStatus() ? ? ? 返回當(dāng)前數(shù)據(jù)庫是否為共享數(shù)據(jù)庫 ?
db.removeUser(username) ? ? ? ?刪除用戶 ?
db.repairDatabase() ? ? ? ? ? ?修復(fù)當(dāng)前數(shù)據(jù)庫 ?
db.resetError() ?
db.runCommand(cmdObj) ? ? ? ? ?run a database command. if cmdObj is a string, turns it into {cmdObj:1} ?
db.setProfilingLevel(level) ? ?設(shè)置profile level 0=off,1=slow,2=all ?
db.shutdownServer() ? ? ? ? ? ?關(guān)閉當(dāng)前服務(wù)程序 ?
db.stats() ? ? ? ? ? ? ? ? ? ? ? 返回當(dāng)前數(shù)據(jù)庫的狀態(tài)信息
db.version() ? ? ? ? ? ? ? ? ? 返回當(dāng)前程序的版本信息
表的幫助,格式:db.表名.help()
db.test.find({id:10}) ? ? ? ? ?返回test數(shù)據(jù)集ID=10的數(shù)據(jù)集 ?
db.test.find({id:10}).count() ?返回test數(shù)據(jù)集ID=10的數(shù)據(jù)總數(shù) ?
db.test.find({id:10}).limit(2) 返回test數(shù)據(jù)集ID=10的數(shù)據(jù)集從第二條開始的數(shù)據(jù)集 ?
db.test.find({id:10}).skip(8) ?返回test數(shù)據(jù)集ID=10的數(shù)據(jù)集從0到第八條的數(shù)據(jù)集 ?
db.test.find({id:10}).limit(2).skip(8) ?返回test數(shù)據(jù)集ID=1=的數(shù)據(jù)集從第二條到第八條的數(shù)據(jù) ?
db.test.find({id:10}).sort() ? 返回test數(shù)據(jù)集ID=10的排序數(shù)據(jù)集 ?
db.test.findOne([query]) ? ? ? 返回符合條件的一條數(shù)據(jù) ?
db.test.getDB() ? ? ? ? ? ? ? ?返回此數(shù)據(jù)集所屬的數(shù)據(jù)庫名稱 ?
db.test.getIndexes() ? ? ? ? ? 返回些數(shù)據(jù)集的索引信息 ?
db.test.group({key:...,initial:...,reduce:...[,cond:...]}) ? ?返回分組信息 ?
db.test.mapReduce(mayFunction,reduceFunction,) ?這個有點(diǎn)像存儲過程 ?
db.test.remove(query) ? ? ? ? ? ? ? ? ? ? ?在數(shù)據(jù)集中刪除一條數(shù)據(jù) ?
db.test.renameCollection(newName) ? ? ? ? ?重命名些數(shù)據(jù)集名稱 ?
db.test.save(obj) ? ? ? ? ? ? ? ? ? ? ? ? ?往數(shù)據(jù)集中插入一條數(shù)據(jù) ?
db.test.stats() ? ? ? ? ? ? ? ? ? ? ? ? ? ?返回此數(shù)據(jù)集的狀態(tài) ?
db.test.storageSize() ? ? ? ? ? ? ? ? ? ? ?返回此數(shù)據(jù)集的存儲大小 ?
db.test.totalIndexSize() ? ? ? ? ? ? ? ? ? 返回此數(shù)據(jù)集的索引文件大小 ?
db.test.totalSize() ? ? ? ? ? ? ? ? ? ? ? ?返回些數(shù)據(jù)集的總大小 ?
db.test.update(query,object[,upsert_bool]) 在此數(shù)據(jù)集中更新一條數(shù)據(jù) ?
db.test.validate() ? ? ? ? ? ? ? ? ? ? ? ? 驗(yàn)證此數(shù)據(jù)集 ?
db.test.getShardVersion() ? ? ? ? ? ? ? ? ?返回?cái)?shù)據(jù)集共享版本號??
版本一:
1 ) . 大于,小于,大于或等于,小于或等于
$gt:大于
$lt:小于
$gte:大于或等于
$lte:小于或等于
例子:
db.collection.find({ "field" : { $gt: value } } );? // greater than? : field > valuedb.collection.find({ "field" : { $lt: value } } );? // less than? :? field= valuedb.collection.find({ "field" : { $lte: value } } );? // less than or equal to : field<=value
如查詢j大于3,小于4:
db.things.find({j : {$lt: 3}});
db.things.find({j : {$gte: 4}});
也可以合并在一條語句內(nèi):
db.collection.find({ "field" : { $gt: value1, $lt: value2 } } );? ? // value1 < field < value
2) 不等于 $ne
例子:
db.things.find( { x : { $ne : 3 } } );
3) in 和 not in ($in $nin)
語法:
db.collection.find( { "field" : { $in : array } } );
例子:
db.things.find({j:{$in: [2,4,6]}});
db.things.find({j:{$nin: [2,4,6]}});
4) 取模運(yùn)算$mod
如下面的運(yùn)算:
db.things.find( "this.a % 10 == 1")
可用$mod代替:
db.things.find( { a : { $mod : [ 10 , 1 ] } } )
5)? $all
$all和$in類似,但是他需要匹配條件內(nèi)所有的值:
如有一個對象:
{ a: [ 1, 2, 3 ] }
下面這個條件是可以匹配的:
db.things.find( { a: { $all: [ 2, 3 ] } } );
但是下面這個條件就不行了:
db.things.find( { a: { $all: [ 2, 3, 4 ] } } );
6)? $size
$size是匹配數(shù)組內(nèi)的元素?cái)?shù)量的,如有一個對象:{a:["foo"]},他只有一個元素:
下面的語句就可以匹配:
db.things.find( { a : { $size: 1 } } );
官網(wǎng)上說不能用來匹配一個范圍內(nèi)的元素,如果想找$size<5之類的,他們建議創(chuàng)建一個字段來保存元素的數(shù)量。
You cannot use?$size?to find a range of sizes (for example: arrays with more than 1 element). If you need to query for a range, create an extra?size?field that you increment when you add elements.
7)$exists
$exists用來判斷一個元素是否存在:
如:
db.things.find( { a : { $exists : true } } ); // 如果存在元素a,就返回
db.things.find( { a : { $exists : false } } ); // 如果不存在元素a,就返回
8)? $type
$type?基于bsontype來匹配一個元素的類型,像是按照類型ID來匹配,不過我沒找到bson類型和id對照表。
db.things.find( { a : { $type : 2 } } ); // matches if a is a string
db.things.find( { a : { $type : 16 } } ); // matches if a is an int
9)正則表達(dá)式
mongo支持正則表達(dá)式,如:
db.customers.find( { name : /acme.*corp/i } ); // 后面的i的意思是區(qū)分大小寫
10)? 查詢數(shù)據(jù)內(nèi)的值
下面的查詢是查詢colors內(nèi)red的記錄,如果colors元素是一個數(shù)據(jù),數(shù)據(jù)庫將遍歷這個數(shù)組的元素來查詢。
db.things.find( { colors : "red" } );
11) $elemMatch
如果對象有一個元素是數(shù)組,那么$elemMatch可以匹配內(nèi)數(shù)組內(nèi)的元素:
> t.find( { x : { $elemMatch : { a : 1, b : { $gt : 1 } } } } )?
{ "_id" : ObjectId("4b5783300334000000000aa9"),?
"x" : [ { "a" : 1, "b" : 3 }, 7, { "b" : 99 }, { "a" : 11 } ]
}
$elemMatch : { a : 1, b : { $gt : 1 } } 所有的條件都要匹配上才行。
注意,上面的語句和下面是不一樣的。
> t.find( { "x.a" : 1, "x.b" : { $gt : 1 } } )
$elemMatch是匹配{?"a"?: 1,?"b"?: 3 },而后面一句是匹配{?"b"?: 99 }, {?"a"?: 11 }
12)? 查詢嵌入對象的值
db.postings.find( { "author.name" : "joe" } );
注意用法是author.name,用一個點(diǎn)就行了。更詳細(xì)的可以看這個鏈接:dot notation
舉個例子:
> db.blog.save({ title : "My First Post", author: {name : "Jane", id : 1}})
如果我們要查詢 authors name 是Jane的, 我們可以這樣:
> db.blog.findOne({"author.name" : "Jane"})
如果不用點(diǎn),那就需要用下面這句才能匹配:
db.blog.findOne({"author" : {"name" : "Jane", "id" : 1}})
下面這句:
db.blog.findOne({"author" : {"name" : "Jane"}})
是不能匹配的,因?yàn)閙ongodb對于子對象,他是精確匹配。
13) 元操作符 $not 取反
如:
db.customers.find( { name : { $not : /acme.*corp/i } } );
db.things.find( { a : { $not : { $mod : [ 10 , 1 ] } } } );
mongodb還有很多函數(shù)可以用,如排序,統(tǒng)計(jì)等,請參考原文。
mongodb目前沒有或(or)操作符,只能用變通的辦法代替,可以參考下面的鏈接:
http://www.mongodb.org/display/DOCS/OR+operations+in+query+expressions
版本二:
shell 環(huán)境下的操作:
???1.??超級用戶相關(guān):
?????????1. #進(jìn)入數(shù)據(jù)庫admin
???????????? use admin
?????????2. #增加或修改用戶密碼
??????????db.addUser('name','pwd')
?????????3. #查看用戶列表
??????????db.system.users.find()
?????????4. #用戶認(rèn)證
??????????db.auth('name','pwd')
?????????5. #刪除用戶
??????????db.removeUser('name')
?????????6. #查看所有用戶
??????????show users
?????????7. #查看所有數(shù)據(jù)庫
??????????show dbs
?????????8. #查看所有的collection
??????????show collections
?????????9. #查看各collection的狀態(tài)
??????????db.printCollectionStats()
????????10. #查看主從復(fù)制狀態(tài)
??????????db.printReplicationInfo()
????????11. #修復(fù)數(shù)據(jù)庫
??????????db.repairDatabase()
????????12. #設(shè)置記錄profiling,0=off 1=slow 2=all
??????????db.setProfilingLevel(1)
????????13. #查看profiling
??????????show profile
????????14. #拷貝數(shù)據(jù)庫
??????????db.copyDatabase('mail_addr','mail_addr_tmp')
????????15. #刪除collection
??????????db.mail_addr.drop()
????????16. #刪除當(dāng)前的數(shù)據(jù)庫
??????????db.dropDatabase()
???2.?增刪改
?????????1. #存儲嵌套的對象
???????????? db.foo.save({'name':'ysz','address':{'city':'beijing','post':100096},'phone':[138,139]})
?????????2. #存儲數(shù)組對象
???????????? db.user_addr.save({'Uid':'yushunzhi@sohu.com','Al':['test-1@sohu.com','test-2@sohu.com']})
?????????3. #根據(jù)query條件修改,如果不存在則插入,允許修改多條記錄
????????????db.foo.update({'yy':5},{'$set':{'xx':2}},upsert=true,multi=true)
?????????4. #刪除yy=5的記錄
????????????db.foo.remove({'yy':5})
?????????5. #刪除所有的記錄
????????????db.foo.remove()
???3.?索引
?????????1. #增加索引:1(ascending),-1(descending)
?????????2. db.foo.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
?????????3. #索引子對象
?????????4. db.user_addr.ensureIndex({'Al.Em': 1})
?????????5. #查看索引信息
?????????6. db.foo.getIndexes()
?????????7. db.foo.getIndexKeys()
?????????8. #根據(jù)索引名刪除索引
?????????9. db.user_addr.dropIndex('Al.Em_1')
???4.?查詢
?????????1. #查找所有
????????2. db.foo.find()
????????3. #查找一條記錄
????????4. db.foo.findOne()
????????5. #根據(jù)條件檢索10條記錄
????????6. db.foo.find({'msg':'Hello 1'}).limit(10)
????????7. #sort排序
????????8. db.deliver_status.find({'From':'ixigua@sina.com'}).sort({'Dt',-1})
?????????9. db.deliver_status.find().sort({'Ct':-1}).limit(1)
????????10. #count操作
????????11. db.user_addr.count()
????????12. #distinct操作,查詢指定列,去重復(fù)
????????13. db.foo.distinct('msg')
????????14. #”>=”操作
????????15. db.foo.find({"timestamp": {"$gte" : 2}})
????????16. #子對象的查找
????????17. db.foo.find({'address.city':'beijing'})
???5.?管理
?????????1. #查看collection數(shù)據(jù)的大小
?????????2. db.deliver_status.dataSize()
?????????3. #查看colleciont狀態(tài)
?????????4. db.deliver_status.stats()
?????????5. #查詢所有索引的大小
?????????6. db.deliver_status.totalIndexSize()
6.??高級查詢
條件操作符
$gt : >
$lt : <
$gte: >=
$lte: <=
$ne : !=、<>
$in : in
$nin: not in
$all: all
$not:?反匹配(1.3.3及以上版本)
查詢?name <> "bruce" and age >= 18?的數(shù)據(jù)
db.users.find({name: {$ne: "bruce"}, age: {$gte: 18}});
查詢?creation_date > '2010-01-01' and creation_date <= '2010-12-31'?的數(shù)據(jù)
db.users.find({creation_date:{$gt:new Date(2010,0,1), $lte:new Date(2010,11,31)});
查詢?age in (20,22,24,26)?的數(shù)據(jù)
db.users.find({age: {$in: [20,22,24,26]}});
查詢?age取模10等于0?的數(shù)據(jù)
db.users.find('this.age % 10 == 0');
或者
db.users.find({age : {$mod : [10, 0]}});
匹配所有
db.users.find({favorite_number : {$all : [6, 8]}});
可以查詢出{name: 'David', age: 26, favorite_number: [ 6, 8, 9 ] }
可以不查詢出{name: 'David', age: 26, favorite_number: [ 6, 7, 9 ] }
查詢不匹配name=B*帶頭的記錄
db.users.find({name: {$not: /^B.*/}});
查詢?age取模10不等于0?的數(shù)據(jù)
db.users.find({age : {$not: {$mod : [10, 0]}}});
#返回部分字段
選擇返回age和_id字段(_id字段總是會被返回)
db.users.find({}, {age:1});
db.users.find({}, {age:3});
db.users.find({}, {age:true});
db.users.find({ name : "bruce" }, {age:1});
0為false,?非0為true
選擇返回age、address和_id字段
db.users.find({ name : "bruce" }, {age:1, address:1});
排除返回age、address和_id字段
db.users.find({}, {age:0, address:false});
db.users.find({ name : "bruce" }, {age:0, address:false});
數(shù)組元素個數(shù)判斷
對于{name: 'David', age: 26, favorite_number: [ 6, 7, 9 ] }記錄
匹配db.users.find({favorite_number: {$size: 3}});
不匹配db.users.find({favorite_number: {$size: 2}});
$exists判斷字段是否存在
查詢所有存在name字段的記錄
db.users.find({name: {$exists: true}});
查詢所有不存在phone字段的記錄
db.users.find({phone: {$exists: false}});
$type判斷字段類型
查詢所有name字段是字符類型的
db.users.find({name: {$type: 2}});
查詢所有age字段是整型的
db.users.find({age: {$type: 16}});
對于字符字段,可以使用正則表達(dá)式
查詢以字母b或者B帶頭的所有記錄
db.users.find({name: /^b.*/i});
$elemMatch(1.3.1及以上版本)
為數(shù)組的字段中匹配其中某個元素
Javascript查詢和$where查詢
查詢?age > 18?的記錄,以下查詢都一樣
db.users.find({age: {$gt: 18}});
db.users.find({$where: "this.age > 18"});
db.users.find("this.age > 18");
f = function() {return this.age > 18} db.users.find(f);
排序sort()
以年齡升序asc
db.users.find().sort({age: 1});
以年齡降序desc
db.users.find().sort({age: -1});
限制返回記錄數(shù)量limit()
返回5條記錄
db.users.find().limit(5);
返回3條記錄并打印信息
db.users.find().limit(3).forEach(function(user) {print('my age is ' + user.age)});
結(jié)果
my age is 18
my age is 19
my age is 20
限制返回記錄的開始點(diǎn)skip()
從第3條記錄開始,返回5條記錄(limit 3, 5)
db.users.find().skip(3).limit(5);
查詢記錄條數(shù)count()
db.users.find().count();
db.users.find({age:18}).count();
以下返回的不是5,而是user表中所有的記錄數(shù)量
db.users.find().skip(10).limit(5).count();
如果要返回限制之后的記錄數(shù)量,要使用count(true)或者count(非0)
db.users.find().skip(10).limit(5).count(true);
分組group()
假設(shè)test表只有以下一條數(shù)據(jù)
{ domain: "www.mongodb.org"
, invoked_at: {d:"2009-11-03", t:"17:14:05"}
, response_time: 0.05
, http_action: "GET /display/DOCS/Aggregation"
}
使用group統(tǒng)計(jì)test表11月份的數(shù)據(jù)count:count(*)、total_time:sum(response_time)、avg_time:total_time/count;
db.test.group(
{ cond: {"invoked_at.d": {$gt: "2009-11", $lt: "2009-12"}}
, key: {http_action: true}
, initial: {count: 0, total_time:0}
, reduce: function(doc, out){ out.count++; out.total_time+=doc.response_time }
, finalize: function(out){ out.avg_time = out.total_time / out.count }
} );
[
{
"http_action" : "GET /display/DOCS/Aggregation",
"count" : 1,
"total_time" : 0.05,
"avg_time" : 0.05
}
]
MongoDB 高級聚合查詢
MongoDB版本為:2.0.8?
系統(tǒng)為:64位Ubuntu 12.04

如你所見,我盡量的模擬現(xiàn)實(shí)生活中的場景。這是一個人的實(shí)體,他有基本的manId,?manName, 有朋友[myFriends],有喜歡的水果[fruits],而且每種水果都有喜歡的權(quán)重。
很不好的是你還看見了有個“_class”字段? 因?yàn)槲沂荍ava開發(fā)者, 我還喜歡用Spring,因此我選用了Spring Data Mongo的類庫[也算是框架吧,但是我不這么覺得]。
現(xiàn)在有很多人Spring見的膩了也開始煩了。是的,Spring野心很大,他幾乎想要壟斷Java方面的任何事情。沒辦法我從使用Spring后就離不開他,以至于其他框架基本上都不用學(xué)。我學(xué)了Spring的很多,諸如:Spring Security/Spring Integration/Spring Batch等。。。不發(fā)明輪子的他已經(jīng)提供了編程里的很多場景,我利用那些場景解決了工作中的很多問題,也使我的工作變得很高效。從而我又時間學(xué)到它更多。Spring Data Mongo封裝了mongodb java driver,提供了和SpringJDBC/Template一致編程風(fēng)格的MongoTemplate。
不說廢話了,我們直接來MongoDB吧。
Max 和Min
我和同事在測試Mongo時,索引還寫了不到一半,他想查詢某個字段的最大值,結(jié)果找了半天文檔也沒找到關(guān)于max的函數(shù)。我也很納悶這是常規(guī)函數(shù)啊怎么不提供? 后來經(jīng)過翻閱資料確定Mongo確實(shí)不提供直接的max和min函數(shù)。但是可以通過間接的方式[sort?和?limit]實(shí)現(xiàn)這個。
要查詢最大值我們只需要把結(jié)果集按照降序排列,取第一個值就是了。
如我的例子,我想取得集合中年齡最大的人。
1db.person.find({}).sort({"age": -1}).limit(1)
相反如果想要年齡最小的人,只需要把sort中改為{“age”:1}就可以了。
當(dāng)然我們使用了sort,對于小數(shù)量的文檔是沒問題的。當(dāng)對于大量數(shù)據(jù)需要給age建立索引,否則這個操作很耗時。
distinct
MongoDB的destinct命令是獲取特定字段中不同值列表的最簡單工具。該命令適用于普通字段,數(shù)組字段[myFriends]和數(shù)組內(nèi)嵌文檔[fruits].
如上面的圖片,我認(rèn)為fruits和myFriends字段是不同的。網(wǎng)上很多資料和例子都沒說到這個情景,因?yàn)槲覀円矘I(yè)務(wù)是fruits這樣的模型,我測試了。對于fruits.fruitId他也是可行的。
如上面的表結(jié)構(gòu),我想統(tǒng)計(jì)所有的喜歡的水果。
1db.person.distinct("fruits.fruitId")?// 查找對象里引入對象的值,直接加.
?他成功執(zhí)行了。輸出如:
1[?"aaa",?"bbb",?"ccc",?"www",?"xxx",?"yyy",?"zzz",?"rrr"]
?我想統(tǒng)計(jì)集合中共有多少個人[按名字吧]
1db.person.distinct("manName")
?我想統(tǒng)計(jì)指定個數(shù)的人的共同關(guān)注的朋友。
1db.person.distinct("myFriends", {"manName": {"$in": ["ZhenQin",?"YangYan"]}})
?輸出如:
1[?"234567",?"345678",?"456789",?"987654",?"ni",?"wo"]