MongoDB高級查詢用法

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。

見:http://static.springsource.org/spring-data/data-mongodb/docs/current/api/org/springframework/data/mongodb/core/MongoTemplate.html

不說廢話了,我們直接來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"]

參考:https://www.cnblogs.com/t2xingzhe/p/3555268.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容