日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

mongoDB入门必读(概念与实战并重)

發(fā)布時(shí)間:2025/1/21 编程问答 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mongoDB入门必读(概念与实战并重) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、概述
MongoDB是一個(gè)基于分布式文件存儲(chǔ)的數(shù)據(jù)庫(kù)開(kāi)源項(xiàng)目。由C++語(yǔ)言編寫(xiě)。旨在為WEB應(yīng)用提供可護(hù)展的高性能數(shù)據(jù)存儲(chǔ)解決方案。
MongoDB是一個(gè)介于關(guān)系數(shù)據(jù)庫(kù)和非關(guān)系數(shù)據(jù)庫(kù)之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫(kù)當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫(kù)的。他支持的數(shù)據(jù)結(jié)構(gòu)非常松散,是類(lèi)似json的bjson格式,因此可以存儲(chǔ)比較復(fù)雜的數(shù)據(jù)類(lèi)型。Mongo最大的特點(diǎn)是他支持的查詢(xún)語(yǔ)言非常強(qiáng)大,其語(yǔ)法有點(diǎn)類(lèi)似于面向?qū)ο蟮牟樵?xún)語(yǔ)言,幾乎可以實(shí)現(xiàn)類(lèi)似關(guān)系數(shù)據(jù)庫(kù)單表查詢(xún)的絕大部分功能,而且還支持對(duì)數(shù)據(jù)建立索引。?

Mongo主要解決的是海量數(shù)據(jù)的訪問(wèn)效率問(wèn)題,根據(jù)官方的文檔,當(dāng)數(shù)據(jù)量達(dá)到50GB以上的時(shí)候,Mongo的數(shù)據(jù)庫(kù)訪問(wèn)速度是MySQL的10倍以上。Mongo的并發(fā)讀寫(xiě)效率不是特別出色,根據(jù)官方提供的性能測(cè)試表明,大約每秒可以處理0.5萬(wàn)-1.5次讀寫(xiě)請(qǐng)求。

因?yàn)镸ongo主要是支持海量數(shù)據(jù)存儲(chǔ)的,所以Mongo還自帶了一個(gè)出色的分布式文件系統(tǒng)GridFS,可以支持海量的數(shù)據(jù)存儲(chǔ),但我也看到有些評(píng)論認(rèn)為GridFS性能不佳,有待驗(yàn)證。?

最后由于Mongo可以支持復(fù)雜的數(shù)據(jù)結(jié)構(gòu),而且?guī)в袕?qiáng)大的數(shù)據(jù)查詢(xún)功能,因此非常受到歡迎,很多項(xiàng)目都考慮用MongoDB來(lái)替代MySQL來(lái)實(shí)現(xiàn)不是特別復(fù)雜的Web應(yīng)用,比方說(shuō) why we migrated from MySQL to MongoDB就是一個(gè)真實(shí)的從MySQL遷移到MongoDB的案例,由于數(shù)據(jù)量實(shí)在太大,所以遷移到了Mongo上面,數(shù)據(jù)查詢(xún)的速度得到了非常顯著的提升。?

MongoDB也有一個(gè)ruby的項(xiàng)目 MongoMapper,是模仿Merb的DataMapper編寫(xiě)的MongoDB的接口,使用起來(lái)非常簡(jiǎn)單,幾乎和DataMapper一模一樣,功能非常強(qiáng)大易用。?

總結(jié)起來(lái),monggDB的特點(diǎn)是高性能、易部署、易使用,存儲(chǔ)數(shù)據(jù)非常方便。主要功能特性有:

*面向集合存儲(chǔ),易存儲(chǔ)對(duì)象類(lèi)型的數(shù)據(jù)。
*模式自由。
*支持動(dòng)態(tài)查詢(xún)。
*支持完全索引,包含內(nèi)部對(duì)象。
*支持查詢(xún)。
*支持復(fù)制和故障恢復(fù)。
*使用高效的二進(jìn)制數(shù)據(jù)存儲(chǔ),包括大型對(duì)象(如視頻等)。
*自動(dòng)處理碎片,以支持云計(jì)算層次的擴(kuò)展性
*支持RUBY,PYTHON,JAVA,C++,PHP等多種語(yǔ)言。
*文件存儲(chǔ)格式為BSON(一種JSON的擴(kuò)展)
*可通過(guò)網(wǎng)絡(luò)訪問(wèn)

所謂“面向集合”(Collenction-Orented),意思是數(shù)據(jù)被分組存儲(chǔ)在數(shù)據(jù)集中,被稱(chēng)為一個(gè)集合(Collenction)。每個(gè)集合在數(shù)據(jù)庫(kù)中都有一個(gè)唯一的標(biāo)識(shí)名,并且可以包含無(wú)限數(shù)目的文檔。集合的概念類(lèi)似關(guān)系型數(shù)據(jù)庫(kù)(RDBMS)里的表(table),不同的是它不需要定義任何模式(schema)。
模式自由(schema-free),意味著對(duì)于存儲(chǔ)在mongodb數(shù)據(jù)庫(kù)中的文件,我們不需要知道它的任何結(jié)構(gòu)定義。如果需要的話,你完全可以把不同結(jié)構(gòu)的文件存儲(chǔ)在同一個(gè)數(shù)據(jù)庫(kù)里。
存儲(chǔ)在集合中的文檔,被存儲(chǔ)為鍵-值對(duì)的形式。鍵用于唯一標(biāo)識(shí)一個(gè)文檔,為字符串類(lèi)型,而值則可以是各中復(fù)雜的文件類(lèi)型。我們稱(chēng)這種存儲(chǔ)形式為BSON(Binary Serialized dOcument Format)。

MongoDB的優(yōu)點(diǎn)

  • 高性能,速度非常快(如果你的內(nèi)存足夠的話)
  • 沒(méi)有固定的表結(jié)構(gòu),不用為了修改表結(jié)構(gòu)而進(jìn)行數(shù)據(jù)遷移
  • 查詢(xún)語(yǔ)言簡(jiǎn)單,容易上手
  • 使用Sharding實(shí)現(xiàn)水平擴(kuò)展
  • 部署方便

使用MongoDB,你得記住以下幾點(diǎn):

  • MongoDB 假設(shè)你有大磁盤(pán)空間
  • MongoDB 假設(shè)你的內(nèi)存也足夠大于放下你的熱數(shù)據(jù)
  • MongoDB 假設(shè)你是部署在64位系統(tǒng)上的(32位有2G的限制,試用還可以)
  • MongoDB 假設(shè)你的系統(tǒng)是little-endian的
  • MongoDB 假設(shè)你有多臺(tái)機(jī)器(并不專(zhuān)注于單機(jī)可靠性)
  • MongoDB 假設(shè)你希望用安全換性能,同時(shí)允許你用性能換安全

MongoDB在下面領(lǐng)域不太擅長(zhǎng)

  • 不太穩(wěn)定,特別是auto-sharding目前還有很多問(wèn)題
  • 不支持SQL,這意味著你很多通過(guò)SQL接口的工具不再適用
  • 持久化,MongoDB單機(jī)可靠性不太好,宕機(jī)可能丟失一段時(shí)間的數(shù)據(jù)
  • 相關(guān)文檔比較少,新功能都有這個(gè)問(wèn)題
  • 相關(guān)人才比較難找,這也是新功能的問(wèn)題之一?


二、安裝

MongoDB服務(wù)端可運(yùn)行在Linux、Windows或OS X平臺(tái),支持32位和64位應(yīng)用,默認(rèn)端口為27017。推薦運(yùn)行在64位平臺(tái),因?yàn)镸ongoDB

在32位模式運(yùn)行時(shí)支持的最大文件尺寸為2GB。MongoDB把數(shù)據(jù)存儲(chǔ)在文件中(默認(rèn)路徑為:/data/db),為提高效率使用內(nèi)存映射文件進(jìn)行管理。

(一)Linux/OS X下:
1 建立數(shù)據(jù)目錄
mkdir -p /data/db
2 下載壓縮包
curl -O?http://downloads.mongodb.org/linux/mongodb-linux-i686-latest.tgz
3 解壓縮文件
tar xzf mongodb-linux-i386-latest.tgz
4 啟動(dòng)服務(wù)
bin/mongod run &
5 使用自帶客戶(hù)端連接
/bin/mongo
6 測(cè)試
db.foo.save( { a : 1 } )
db.foo.findOne()

(二)windows下:

1 建立數(shù)據(jù)目錄c:\data\db
2 下載壓縮包,解壓文件
3 啟動(dòng)服務(wù)
bin\mongod.exe run
4 自帶客戶(hù)端
bin\mongon.exe

在LINUX和WINDOWS系統(tǒng)下的使用大同小異,不同的地方主要是默認(rèn)的數(shù)據(jù)存儲(chǔ)目錄。LINUX類(lèi)系統(tǒng)下存放在/data/db下,而WINDOWS

會(huì)存放在C:\data\db下。可以在啟動(dòng)時(shí)使用--dbpath參數(shù)指定存儲(chǔ)目錄并啟動(dòng)。如:bin\mongod.exe --dbpath d:\data\mongo

常用啟動(dòng)參數(shù):
run 直接啟動(dòng)。例:./mongod run
--dbpath 指定特定存儲(chǔ)目錄啟動(dòng),若目錄不存在則創(chuàng)建。例:./mongod --dbpath /var/data/mongo
--port 指定端口啟動(dòng)。例:./mongod --port 12345

停止MONGO服務(wù):
方法1:服務(wù)端停止,可使用Ctrl+C
方法2:在客戶(hù)端停止,可先連接客戶(hù)端
./mongo
并使用命令
db.shutdownerver()
然后退出客戶(hù)端
exit

三、mongoDB常用命令

1、與Mql對(duì)照

?

MySQL

MongoDB

說(shuō)明

mysqld

mongod

服務(wù)器守護(hù)進(jìn)程

mysql

mongo

客戶(hù)端工具

mysqldump

mongodump

邏輯備份工具

mysql

mongorestore

邏輯恢復(fù)工具

?

db.repairDatabase()

修復(fù)數(shù)據(jù)庫(kù)

mysqldump

mongoexport

數(shù)據(jù)導(dǎo)出工具

source

mongoimport

數(shù)據(jù)導(dǎo)入工具

grant * privileges on *.* to …

Db.addUser()

Db.auth()

新建用戶(hù)并權(quán)限

show databases

show dbs

顯示庫(kù)列表

Show tables

Show collections

顯示表列表

Show slave status

Rs.status

查詢(xún)主從狀態(tài)

Create table users(a int, b int)

db.createCollection("mycoll", {capped:true,

size:100000})?另:可隱式創(chuàng)建表。

創(chuàng)建表

Create INDEX idxname ON users(name)

db.users.ensureIndex({name:1})

創(chuàng)建索引

Create INDEX idxname ON users(name,ts DESC)

db.users.ensureIndex({name:1,ts:-1})

創(chuàng)建索引

Insert into users values(1, 1)

db.users.insert({a:1, b:1})

插入記錄

Select a, b from users

db.users.find({},{a:1, b:1})

查詢(xún)表

Select * from users

db.users.find()

查詢(xún)表

Select * from users where age=33

db.users.find({age:33})

條件查詢(xún)

Select a, b from users where age=33

db.users.find({age:33},{a:1, b:1})

條件查詢(xún)

select * from users where age<33

db.users.find({'age':{$lt:33}})

條件查詢(xún)

select * from users where age>33 and age<=40

db.users.find({'age':{$gt:33,$lte:40}})

條件查詢(xún)



select * from users where a=1 and b='q'

db.users.find({a:1,b:'q'})

條件查詢(xún)

select * from users where a=1 or b=2

db.users.find( { $or : [ { a : 1 } , { b : 2 } ] } )

條件查詢(xún)

select * from users limit 1

db.users.findOne()

條件查詢(xún)

select * from users where name like "%Joe%"

db.users.find({name:/Joe/})

模糊查詢(xún)

select * from users where name like "Joe%"

db.users.find({name:/^Joe/})

模糊查詢(xún)

select count(1) from users

Db.users.count()

獲取表記錄數(shù)

select count(1) from users where age>30

db.users.find({age: {'$gt': 30}}).count()

獲取表記錄數(shù)

select DISTINCT last_name from users

db.users.distinct('last_name')

去掉重復(fù)值

select * from users ORDER BY name

db.users.find().sort({name:-1})

排序

select * from users ORDER BY name DESC

db.users.find().sort({name:-1})

排序

EXPLAIN select * from users where z=3

db.users.find({z:3}).explain()

獲取存儲(chǔ)路徑

update users set a=1 where b='q'

db.users.update({b:'q'}, {$set:{a:1}}, false, true)

更新記錄

update users set a=a+2 where b='q'

db.users.update({b:'q'}, {$inc:{a:2}}, false, true)

更新記錄

delete from users where z="abc"

db.users.remove({z:'abc'})

刪除記錄

?

db. users.remove()

刪除所有的記錄

drop database IF EXISTS test;

use test

db.dropDatabase()

刪除數(shù)據(jù)庫(kù)

drop table IF EXISTS test;

db.mytable.drop()

刪除表/collection

?

db.addUser(‘test’, ’test’)

添加用戶(hù)

readOnly-->false

?

db.addUser(‘test’, ’test’, true)

添加用戶(hù)

readOnly-->true

?

db.addUser("test","test222")

更改密碼

?

db.system.users.remove({user:"test"})

或者db.removeUser('test')

刪除用戶(hù)



? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

use admin

超級(jí)用戶(hù)

?

db.auth(‘test’, ‘test’)

用戶(hù)授權(quán)

?

db.system.users.find()

查看用戶(hù)列表

?

show users

查看所有用戶(hù)

?

db.printCollectionStats()

查看各collection的狀態(tài)

?

db.printReplicationInfo()

查看主從復(fù)制狀態(tài)

?

show profile

查看profiling

?

db.copyDatabase('mail_addr','mail_addr_tmp')

拷貝數(shù)據(jù)庫(kù)

?

db.users.dataSize()

查看collection數(shù)據(jù)的大小

?

db. users.totalIndexSize()

查詢(xún)索引的大小

?


2、shell數(shù)據(jù)操作實(shí)戰(zhàn)?

插入數(shù)據(jù)到集合

下面我們來(lái)建立一個(gè)test的集合并寫(xiě)入一些數(shù)據(jù). 建立兩個(gè)對(duì)象, j 和 t , 并保存到集合中去.
在例子里 ‘>’ 來(lái)表示是 shell 輸入提示符

> j = { name : "mongo" };{"name" : "mongo"}> t = { x : 3 };{ "x" : 3 }> db.things.save(j);> db.things.save(t);> db.things.find();{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}>

有幾點(diǎn)需要注意下 :

  • 不需要預(yù)先建立一個(gè)集合. 在第一次插入數(shù)據(jù)時(shí)候會(huì)自動(dòng)建立.
  • 在例子其實(shí)可以存儲(chǔ)任何結(jié)構(gòu)的數(shù)據(jù), 當(dāng)然在實(shí)際應(yīng)用我們存儲(chǔ)的還是相同元素的集合. 這個(gè)特性其實(shí)可以在應(yīng)用里很靈活, 你不需要類(lèi)似alter table 來(lái)修改你的數(shù)據(jù)結(jié)構(gòu)
  • 每次插入數(shù)據(jù)時(shí)候?qū)ο蠖紩?huì)有一個(gè)ID, 名字叫 _id.
  • 當(dāng)你運(yùn)行不同的例子, 你的對(duì)象ID值都是不同的.

下面再加點(diǎn)數(shù)據(jù):

> for( var i = 1; i < 10; i++ ) db.things.save( { x:4, j:i } ); > db.things.find();{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}

請(qǐng)注意下, 這里循環(huán)次數(shù)是10, 但是只顯示到8, 還有2條數(shù)據(jù)沒(méi)有顯示.

如果想繼續(xù)查詢(xún)下面的數(shù)據(jù)只需要使用 it 命令, 就會(huì)繼續(xù)下面的數(shù)據(jù):

{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}

繼續(xù)

> it{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}{"x" : 4 , "j" : 10 , "_id" : ObjectId("497cf87151712cf7758fbdc6")}

從技術(shù)上講 find() 返回一個(gè)游標(biāo)對(duì)象. 但在上面的例子里, 并沒(méi)有拿到一個(gè)游標(biāo)的變量. 所以 shell 自動(dòng)遍歷游標(biāo), 返回一個(gè)初始化的set, 并允許我們繼續(xù)用 it 迭代輸出.
當(dāng)然我們也可以直接用游標(biāo)來(lái)輸出, 不過(guò)這個(gè)是下一部分的內(nèi)容了.

查詢(xún)數(shù)據(jù)

在沒(méi)有深入查詢(xún)之前, 我們先看看怎么從一個(gè)查詢(xún)中返回一個(gè)游標(biāo)對(duì)象. 可以簡(jiǎn)單的通過(guò) find() 來(lái)查詢(xún), 他返回一個(gè)任意結(jié)構(gòu)的集合. 如果實(shí)現(xiàn)特定的查詢(xún)稍后講解.
實(shí)現(xiàn)上面同樣的查詢(xún), 然后通過(guò) while 來(lái)輸出:

> var cursor = db.things.find();> while (cursor.hasNext()) { print(tojson(cursor.next())); }{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}>

上面的例子顯示了游標(biāo)風(fēng)格的迭代輸出. hasNext() 函數(shù)告訴我們是否還有數(shù)據(jù), 如果有則可以調(diào)用 next() 函數(shù). 這里我們也用了自帶的 tojson() 方法返回一個(gè)標(biāo)準(zhǔn)的 JSON 格式數(shù)據(jù).

當(dāng)我們使用的是 JavaScript shell, 可以用到JS的特性, forEach 就可以輸出游標(biāo)了. 下面的例子就是使用 forEach() 來(lái)循環(huán)輸出:

forEach() 必須定義一個(gè)函數(shù)供每個(gè)游標(biāo)元素調(diào)用.

> db.things.find().forEach( function(x) { print(tojson(x));});{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}>

在 mongo shell 里, 我們也可以把游標(biāo)當(dāng)作數(shù)組來(lái)用 :

> var cursor = db.things.find();> print (tojson(cursor[4]));{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}

使用游標(biāo)時(shí)候請(qǐng)注意占用內(nèi)存的問(wèn)題, 特別是很大的游標(biāo)對(duì)象, 有可能會(huì)內(nèi)存溢出. 所以應(yīng)該用迭代的方式來(lái)輸出.
下面的示例則是把游標(biāo)轉(zhuǎn)換成真實(shí)的數(shù)組類(lèi)型:

> var arr = db.things.find().toArray();> arr[5];{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}

請(qǐng)注意這些特性只是在 mongo shell 里使用, 而不是所有的其他應(yīng)用程序驅(qū)動(dòng)都支持.

MongoDB 游標(biāo)對(duì)象不是沒(méi)有快照 – 如果有其他用戶(hù)在集合里第一次或者最后一次調(diào)用 next(), 你可以得不到游標(biāo)里的數(shù)據(jù). 所以要明確的鎖定你要查詢(xún)的游標(biāo).

指定條件的查詢(xún)

到這里我們已經(jīng)知道怎么從游標(biāo)里實(shí)現(xiàn)一個(gè)查詢(xún)并返回?cái)?shù)據(jù)對(duì)象, 下面就來(lái)看看怎么根據(jù)指定的條件來(lái)查詢(xún).

下面的示例就是說(shuō)明如何執(zhí)行一個(gè)類(lèi)似SQL的查詢(xún), 并演示了怎么在 MongoDB 里實(shí)現(xiàn). 這是在 MongoDB shell 里查詢(xún), 當(dāng)然你也可以用其他的應(yīng)用驅(qū)動(dòng)或者語(yǔ)言來(lái)實(shí)現(xiàn):

SELECT * FROM things WHERE name="mongo" >db.things.find({name:"mongo"}).forEach(function(x) { print(tojson(x));});{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}>SELECT * FROM things WHERE x=4> db.things.find({x:4}).forEach(function(x) { print(tojson(x));});{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}{"x" : 4 , "j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}>

查詢(xún)條件是 { a:A, b:B, … } 類(lèi)似 “where a==A and b==B and …”, 更多的查詢(xún)方式可以參考 Mongo 開(kāi)發(fā)教程部分.

上面顯示的是所有的元素, 當(dāng)然我們也可以返回特定的元素, 類(lèi)似于返回表里某字段的值, 只需要在 find({x:4}) 里指定元素的名字, 比如 j:

SELECT j FROM things WHERE x=4> db.things.find({x:4}, {j:true}).forEach(function(x) { print(tojson(x));});{"j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}{"j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}{"j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}{"j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}{"j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}{"j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}{"j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}{"j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}{"j" : 9 , "_id" : ObjectId("497cf87151712cf7758fbdc5")}>

請(qǐng)注意 “_id” 元素會(huì)一直被返回.

findOne()?

為了方便, mongo shell (其他驅(qū)動(dòng)) 避免游標(biāo)的可能帶來(lái)的開(kāi)銷(xiāo), 提供一個(gè)findOne() 函數(shù). 這個(gè)函數(shù)和 find() 參數(shù)一樣, 不過(guò)他返回游標(biāo)里第一條數(shù)據(jù), 或者返回 null 空數(shù)據(jù)庫(kù).

作為一個(gè)例子, name==’mongo’ 可以用很多方法來(lái)實(shí)現(xiàn), 可以用 next() 來(lái)循環(huán)游標(biāo)(需要校驗(yàn)是否為null), 或者當(dāng)做數(shù)組返回第一個(gè)元素.

但是用 findOne() 方法則更簡(jiǎn)單和高效:

> var mongo = db.things.findOne({name:"mongo"});> print(tojson(mongo));{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}>

findOne 方法更跟 find({name:”mongo”}).limit(1) 一樣.

limit() 查詢(xún)

你可以需要限制結(jié)果集的長(zhǎng)度, 可以調(diào)用 limit 方法.

這是強(qiáng)烈推薦高性能的原因, 通過(guò)限制條數(shù)來(lái)減少網(wǎng)絡(luò)傳輸, 例如:

> db.things.find().limit(3);in cursor for : DBQuery: example.things ->{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}>

更多幫助

除非了一般的 help 之外, 你還可以查詢(xún) help 數(shù)據(jù)庫(kù)和db.whatever 來(lái)查詢(xún)具體的說(shuō)明.

這篇寫(xiě)得常用命令也不錯(cuò)http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html


四、與java結(jié)合

使用JAVA語(yǔ)言操作MONGODB非常簡(jiǎn)單,只要將驅(qū)動(dòng)文件加入到CLASSPATH中就可以使用。



junit-4.11和hamcrest-core-1.3是junit4依賴(lài)包

mongo-java-driver-2.9.3為mongodb的java驅(qū)動(dòng)包

實(shí)戰(zhàn):

import com.mongodb.Mongo;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.MongoAdmin;


1、獲得連接

Mongo db = new Mongo("mydb");
Mongo db = new Mongo("localhost", "mydb");
Mongo db = new Mongo("localhost", 27017, "mydb");

查看mongoDB數(shù)據(jù)庫(kù)列表?
Mongo m = new Mongo();?
for (String s : m.getDatabaseNames()) {?
System.out.println(s);?
}?

刪除一個(gè)數(shù)據(jù)庫(kù)?
Mongo m = new Mongo();?
m.dropDatabase("myDatabaseName");?

2 安全驗(yàn)證(非必選)
MongoDB服務(wù)可以在安全模式運(yùn)行,此時(shí)任何客戶(hù)端要連接數(shù)據(jù)庫(kù)時(shí)需使用用戶(hù)名和密碼。在JAVA中可使用如下方法連接:

boolean auth = db.authenticate(userName, password);

如果用戶(hù)名密碼驗(yàn)證通過(guò),返回值為true,否則為false

3 獲取集合列表
每個(gè)數(shù)據(jù)庫(kù)都存在零個(gè)或多個(gè)集合,需要時(shí)你可以獲得他們的列表:

Set<String> colls = db.getCollectionNames();
for(String s : colls){
System.out.println(s);
}

4 獲得一個(gè)集合
要獲得某個(gè)特定集合,你可以指定集合的名字,并使用getCollection()方法:

DBCollection coll = db.getCollection("testCollection");

當(dāng)你獲取了這個(gè)集合對(duì)象,你就可以對(duì)數(shù)據(jù)進(jìn)行增刪查改之類(lèi)的操作。

查看一個(gè)集合的索引?

List<DBObject> list = coll.getIndexInfo();?
for (DBObject o : list) {?
System.out.println(o);?
}?

5 插入文檔

默認(rèn)ID?
當(dāng)保存的對(duì)象沒(méi)有設(shè)置ID時(shí),mongoDB會(huì)默認(rèn)給該條記錄設(shè)置一個(gè)ID("_id")。?
當(dāng)然你也可以設(shè)置自己指定的ID,如:(在mongoDB中執(zhí)行用db.users.save({_id:1,name:'bruce'});)?


當(dāng)你獲得了一個(gè)集合對(duì)象,你就可以把文檔插入到這個(gè)對(duì)象中。例如,存在一個(gè)JSON式的小文檔:
{
"name" : "MongoDB",
"type" : "database",
"count" : 1,
"info" : {
?? x : 203,
?? y : 102
? }
}
請(qǐng)注意,這個(gè)文檔包含一個(gè)內(nèi)部文檔。我們可以使用BasicDBObject類(lèi)來(lái)創(chuàng)建這個(gè)文檔,并且使用insert()方法方便地將它插入到集

合中。

BasicDBObject doc = new BasicDBObject();
doc.put("name", "MongoDB");
doc.put("type", "database");
doc.put("count", 1);

BasicDBObject info = new BasicDBObject();
info.put("x", 203);
info.put("y", 102);

doc.put("info", info);

coll.insert(doc);

批量插入?
List datas = new ArrayList();?
for (int i=0; i < 100; i++) {?
BasicDBObject bo = new BasicDBObject();?
bo.put("name", "bruce");?
bo.append("age", i);?
datas.add(bo);?
}?
coll.insert(datas);?

6 使用findOne()查找集合中第一個(gè)文檔
要查找我們上一步插入的那個(gè)文檔,可以簡(jiǎn)單地使用findOne()操作來(lái)獲取集合中第一個(gè)文檔。這個(gè)方法返回一個(gè)單一文檔(這是相對(duì)于使用DBCursor的find()操作的返回),這對(duì)于只有一個(gè)文檔或我們剛插入第一個(gè)文檔時(shí)很有用,因?yàn)榇藭r(shí)并不需要使用光標(biāo)。

DBObject myDoc = coll.findOne();
System.out.println(myDoc);

返回類(lèi)似:
{
"_id" : "ac907a1f5b9d5e4a233ed300" ,
"name" : "MongoDB" ,
"type" : 1 ,
"info" : {
? "x" : 203 ,
? "y" : 102} ,
"_ns" : "testCollection"
}

注意_id和_ns元素是由MongoDB自動(dòng)加入你的文檔。記住:MongoDB內(nèi)部存儲(chǔ)使用的元素名是以“_”做為開(kāi)始。

7 加入多種文檔
為了做更多有趣的查詢(xún)?cè)囼?yàn),讓我們向集合中加入多種文檔類(lèi)型,象:
{
"i" : value
}
可以通過(guò)循環(huán)來(lái)實(shí)現(xiàn)

for(int i = 0; i < 100; i++){
coll.insert(new BasicDBObject().append("i", i));
}

注意我們可以在一個(gè)集合中插入不同類(lèi)型的文檔,這就是我們所說(shuō)的“模式自由”(schema-free)。

8 統(tǒng)計(jì)文檔數(shù)量
使用getCount()方法

System.out.println(coll.getCount());

9 使用光標(biāo)(cursor)來(lái)獲取全部文檔
為了獲取集合中的所有文檔,我們可以使用find()方法。這個(gè)方法返回一上DBCursor對(duì)象,來(lái)允許我們將符合查詢(xún)條件的文檔迭代

出來(lái)。

DBCursor cur = coll.find();
while(cur.hasNext()){
System.out.println(cur.next());
}

10 在查詢(xún)中獲取單一文檔
我們可以創(chuàng)建一個(gè)查詢(xún),并傳遞給find()方法來(lái)獲取集合中所有文檔的一個(gè)子集。例如,我們想要查詢(xún)域名為"i",并且值為71的文檔:

BasicDBObject query = new BasicDBObject();
query.put("i", 71);
cur = coll.find(query);
while(cur.hasNext()){
System.out.println(cur.next());
}


類(lèi)轉(zhuǎn)換?
當(dāng)把一個(gè)類(lèi)對(duì)象存到mongoDB后,從mongoDB取出來(lái)時(shí)使用setObjectClass()將其轉(zhuǎn)換回原來(lái)的類(lèi)。?
public class Tweet implements DBObject {?
??? /* ... */?
}?
Tweet myTweet = new Tweet();?
myTweet.put("user", "bruce");?
myTweet.put("message", "fun");?
myTweet.put("date", new Date());?
collection.insert(myTweet);?
//轉(zhuǎn)換?
collection.setObjectClass(Tweet);?
Tweet myTweet = (Tweet)collection.findOne();?

11 使用條件查詢(xún)獲取集合

比較符?
"$gt": 大于?
"$gte":大于等于?
"$lt": 小于?
"$lte":小于等于?
"$in": 包含?

例如,我們想要查詢(xún)所有i>50的文檔:

BasicDBObject query = new BasicDBObject();
query.put("i", new BasicDBObject("$gt", 50));
cur = coll.find(query);
while(cur.hasNext()){
System.out.println(cur.next());
}

當(dāng)然,我們也可以做20 < i <= 30的查詢(xún)

BasicDBObject query = new BasicDBObject();
query.put("i", new BasicDBObject("$gt", 20).append("$lte", 30));
cur = coll.find(query);
while(cur.hasNext()){
System.out.println(cur.next());

}

正則表達(dá)式?
查詢(xún)所有名字匹配 /joh?n/i 的記錄?
Pattern pattern = Pattern.compile("joh?n", CASE_INSENSITIVE);?
BasicDBObject query = new BasicDBObject("name", pattern);?
DBCursor cursor = coll.find(query);?


12 創(chuàng)建索引
MongoDB支持索引,而且很容易在集合上增加索引。要?jiǎng)?chuàng)建索引,只需要指定要加索引的屬性,并且指定升序(1)或降序即可(-1)。

coll.createIndex(new BasicDBObject("i", 1));

13 獲取索引列表

List<DBObject> list = coll.getIndexInfo();
for(DBObject o : list){
System.out.println(o);
}

14 MongoDB管理函數(shù)
管理函數(shù)在com.mongodb.MongoAdmin類(lèi)中定義。
例A:獲取數(shù)據(jù)庫(kù)列表
MongoAdmin admin = new MongoAdmin();
for(String s : admin.getDatabaseNames()){
? System.out.println(s);
}

例B:獲取數(shù)據(jù)庫(kù)對(duì)象
Mongo m = admin.getDB("mydb");

例C:刪除數(shù)據(jù)庫(kù)
admin.dropDatabase("mydb");

15 用DBObject存儲(chǔ)JAVA對(duì)象
MongoDB for JAVA驅(qū)動(dòng)中提供了用于向數(shù)據(jù)庫(kù)中存儲(chǔ)普通對(duì)象的接口DBObject
例如,存在一個(gè)需要存儲(chǔ)的對(duì)象類(lèi)Tweet
public class Tweet implements DBObject{
/*...*/
}
可以使用如下代碼:

Tweet myTweet = new Tweet();
myTweet.put("user", userId);
myTweet.put("message", message);
myTweet.put("date", new Date());

collection.insert(myTweet);

當(dāng)一個(gè)文檔從MongoDB中取出時(shí),它會(huì)自動(dòng)把文檔轉(zhuǎn)換成DBObject接口類(lèi)型,要將它實(shí)例化為你的對(duì)象,需使用

DBCollection.setObjectClass()。
collection.setObjectClass(Tweet);
Tweet myTweet = (Tweet)collection.findOne();

16 JAVA驅(qū)動(dòng)的并發(fā)性
JAVA的MongoDB驅(qū)動(dòng)是線程安全的。如果你將它用在WEB服務(wù)中,可以創(chuàng)建它的一個(gè)單例,并在所有請(qǐng)求中使用它。

然而,如果你需要在一個(gè)會(huì)話(例如HTTP請(qǐng)求)中保證事務(wù)一致性,也許你會(huì)希望在這個(gè)會(huì)話中對(duì)驅(qū)動(dòng)使用同一個(gè)端口。這僅僅在

請(qǐng)求量非常大的環(huán)境中,例如你經(jīng)常會(huì)讀取剛寫(xiě)入的數(shù)據(jù)。
為了這一點(diǎn),你需要使用如下代碼:
Mongo m;
m.restartStart();

// code.........

m.requestDone();


源碼下載地址


參考:

http://www.iteye.com/blogs/tag/NoSQL

http://blog.nosqlfan.com/html/2215.html

http://josh-persistence.iteye.com/blog/1882436

http://www.mongodb.org/display/DOCS/Manual

http://blog.nosqlfan.com/html/342.html

http://myeyeofjava.iteye.com/blog/1296575

http://docs.mongodb.org/ecosystem/drivers/java/



?

總結(jié)

以上是生活随笔為你收集整理的mongoDB入门必读(概念与实战并重)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。