mongodb介绍
一 介紹
???MongoDB是一個基于分布式文件存儲的數據庫。由C++語言編寫。旨在為WEB應用提供可護展的高性能數據存儲解決方案。???一個mongod服務可以有建立多個數據庫,每個數據庫可以有多張表,這里的表名叫collection,每個collection可以存放多個文檔(document),每個文檔都以BSON(binary json)的形式存放于硬盤中,因此可以存儲比較復雜的數據類型。它是以單文檔為單位存儲的,你可以任意給一個或一批文檔新增或刪除字段,而不會對其它文檔造成影響,這就是所謂的schema-free,這也是文檔型數據庫最主要的優點。跟一般的key-value數據庫不一樣的是,它的value中存儲了結構信息,所以你又可以像關系型數據庫那樣對某些域進行讀寫、統計等操作。Mongo最大的特點是他支持的查詢語言非常強大,其語法有點類似于面向對象的查詢語言,幾乎可以實現類似關系數據庫單表查詢的絕大部分功能,而且還支持對數據建立索引。Mongo還可以解決海量數據的查詢效率,根據官方文檔,當數據量達到50GB以上數據時,Mongo數據庫訪問速度是MySQL10 倍以上。
?二 安裝及使用
Linux/OS X下:
1 建立數據目錄
?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 啟動服務
?bin/mongod run &
5 使用自帶客戶端連接
?/bin/mongo
6 測試
windows下:
1 建立數據目錄c:\data\db
2 下載壓縮包,解壓文件
3 啟動服務
?bin\mongod.exe run
4 自帶客戶端
?bin\mongon.exe
在LINUX和WINDOWS系統下的使用大同小異,不同的地方主要是默認的數據存儲目錄。LINUX類系統下存放在/data/db下,而WINDOWS
會存放在C:\data\db下。可以在啟動時使用--dbpath參數指定存儲目錄并啟動。如:bin\mongod.exe --dbpath d:\data\mongo
常用啟動參數:
run 直接啟動。例:./mongod run
--dbpath 指定特定存儲目錄啟動,若目錄不存在則創建。例:./mongod --dbpath /var/data/mongo
--port 指定端口啟動。例:./mongod --port 12345
停止MONGO服務:
方法1:服務端停止,可使用Ctrl+C
方法2:在客戶端停止,可先連接客戶端
?./mongo
?并使用命令
?db.shutdownerver()
?然后退出客戶端
?exit?
三 索引
??? mongodb可以對某個字段建立索引,可以建立組合索引、唯一索引,也可以刪除索引,建立索引就意味著增加空間開銷。默認情況下每個表都會有一個唯一索引:_id,如果插入數據時沒有指定_id,服務會自動生成一個_id,為了充分利用已有索引,減少空間開銷,最好是自己指定一個unique的key為_id,通常用對象的ID比較合適,比如商品的ID。?
四 shell操作數據庫
?
?1.? 超級用戶相關:
???
???? ?1. #進入數據庫admin use admin2. #增加或修改用戶密碼db.addUser('name','pwd')3. #查看用戶列表db.system.users.find()4. #用戶認證db.auth('name','pwd')5. #刪除用戶db.removeUser('name')6. #查看所有用戶show users7. #查看所有數據庫show dbs8. #查看所有的collectionshow collections9. #查看各collection的狀態db.printCollectionStats()10. #查看主從復制狀態db.printReplicationInfo()11. #修復數據庫db.repairDatabase()12. #設置記錄profiling,0=off 1=slow 2=alldb.setProfilingLevel(1)13. #查看profilingshow profile14. #拷貝數據庫db.copyDatabase('mail_addr','mail_addr_tmp')15. #刪除collectiondb.mail_addr.drop()16. #刪除當前的數據庫db.dropDatabase()???
?? 2. 增刪改
???
??? ? 1. #存儲嵌套的對象 db.foo.save({'name':'ysz','address':{'city':'beijing','post':100096},'phone':[138,139]})2. #存儲數組對象 db.user_addr.save({'Uid':'yushunzhi@sohu.com','Al':['test-1@sohu.com','test-2@sohu.com']})3. #根據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. #根據索引名刪除索引9. db.user_addr.dropIndex('Al.Em_1')? ?4. 查詢
???????
?1. #查找所有2. db.foo.find()3. #查找一條記錄4. db.foo.findOne()5. #根據條件檢索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操作,查詢指定列,去重復13. db.foo.distinct('msg')14. #">="操作15. db.foo.find({"timestamp": {"$gte" : 2}})16. #子對象的查找17. db.foo.find({'address.city':'beijing'})?
5. 管理
????????
?1. #查看collection數據的大小2. db.deliver_status.dataSize()3. #查看colleciont狀態4. db.deliver_status.stats()5. #查詢所有索引的大小6. db.deliver_status.totalIndexSize()6.? advanced queries:高級查詢
條件操作符? $gt : >? $lt : <? $gte: >=? $lte: <=? $ne : !=、<>? $in : in? $nin: not in? $all: all? $not: 反匹配(1.3.3及以上版本)?查詢 name <> "bruce" and age >= 18 的數據? db.users.find({name: {$ne: "bruce"}, age: {$gte: 18}});?查詢 creation_date > '2010-01-01' and creation_date <= '2010-12-31' 的數據? db.users.find({creation_date:{$gt:new Date(2010,0,1), $lte:new Date(2010,11,31)});?查詢 age in (20,22,24,26) 的數據? db.users.find({age: {$in: [20,22,24,26]}});?查詢 age取模10等于0 的數據? 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 的數據? 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});? 數組元素個數判斷? 對于{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}});? 對于字符字段,可以使用正則表達式? 查詢以字母b或者B帶頭的所有記錄? db.users.find({name: /^b.*/i});? $elemMatch(1.3.1及以上版本)? 為數組的字段中匹配其中某個元素? 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});? 限制返回記錄數量limit()? 返回5條記錄? db.users.find().limit(5);? 返回3條記錄并打印信息? db.users.find().limit(3).forEach(function(user) {print('my age is ' + user.age)});? 結果? my age is 18? my age is 19? my age is 20? 限制返回記錄的開始點skip()? 從第3條記錄開始,返回5條記錄(limit 3, 5)? db.users.find().skip(3).limit(5);? 查詢記錄條數count()? db.users.find().count();? db.users.find({age:18}).count();? 以下返回的不是5,而是user表中所有的記錄數量? db.users.find().skip(10).limit(5).count();? 如果要返回限制之后的記錄數量,要使用count(true)或者count(非0)? db.users.find().skip(10).limit(5).count(true);? 分組group()? 假設test表只有以下一條數據? { 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統計test表11月份的數據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? }? ] ??五 java應用示例
??? 要使用Java操作MongoDB的話,要到官方網站下載一個驅動包,把包導入后,可以嘗試來操作了(記得一定要開著服務器)
首先介紹一下比較常用的幾個類
Mongo:連接服務器,執行一些數據庫操作的選項,如新建立一個數據庫等
DB:對應一個數據庫,可以用來建立集合等操作
DBCollection:對應一個集合(類似表),可能是我們用得最多的,可以添加刪除記錄等
DBObjec:接口和BasicDBObject對象:表示一個具體的記錄,BasicDBObject實現了DBObject,因為是key-value的數據結構,所以用起來其實和HashMap是基本一致的
DBCursor:用來遍歷取得的數據,實現了Iterable和Iterator
接下來實際的操作一下,代碼如下:
? package?test; ??? import?com.mongodb.*; ?? import?java.net.UnknownHostException; ? import?java.util.Date; ?? import?java.util.List; ?????? public?class?Test?{ ??????? public?static?void?main(String[]?args)?throws?UnknownHostException?{ ???????????? ?Mongo?m?=?new?Mongo(?"localhost"?,?27017?); ????????????? //獲取數據庫對象,如果沒mydb數據庫,自動創建一個 ??????????? DB?db?=?m.getDB("mydb"); ??????????? ?//刪除數據庫對象 ??????????? m.dropDatabase("test"); ????????????? //獲取所有數據庫名稱列表 ?????????? ?for?(String?s?:?m.getDatabaseNames())?{ ?????????????? ?System.out.println(s); ?????????? ?} ??????????? ??????????? //增加一個用戶,密碼需轉換成字符數據 ?? //? db.addUser("admin",?"123456".toCharArray()); ? ?//??System.out.println(db.authenticate("admin",?"123456".toCharArray())); ???????????? ?//驗證數據庫用戶名密碼 ????????? ??boolean?auth?=?db.authenticate("admin",?"123456".toCharArray()); ????? ??????System.out.println("-----------"+auth); ??????????? ??//得到一個集合,可對這個集合進行CRUD操作 ??????? ????DBCollection?coll?=?db.getCollection("adminCollection"); ? ?//?????????DBCollection?coll?=?db.getCollection("userCollection"); ????????????? ??????? ????//統計adminCollection集合中文檔數量 ???????? ???System.out.println("adminCollection?object?count-----"+coll.getCount()); ???? ?????//用到內部文檔組裝數據,然后用集合的insert方法插入 ???????? ?DBObject?object?=?new?BasicDBObject(); ????????? ??object.put("picName",?"d:\\pic\\test\\1.jpg"); ????? ??????object.put("content","ssssssssss"); ??????? ????coll.insert(object); ??????? ????for?(int?i?=?0;?i?<?10;?i++)?{ ?? //?????????????coll.insert(new?BasicDBObject().append("i",?i)); ???? ???????} ????? ?????????//使用findOne()查找集合中第一個文檔 ???? ???????DBObject?myDoc?=?coll.findOne(); ?????? ???? ?System.out.println("the?first?result----"?+?myDoc); ? ?????????//查詢,相當于字段--值的關系 ???? ???????DBObject?dbObject?=?new?BasicDBObject(); ??? ????????dbObject.put("picName",?"d:\\pic\\test\\1.jpg"); ? ?//?????????dbObject.put("_id","c5605578414d384b5e4cc200"); ????? ??????DBCursor?curs?=?coll.find(dbObject); ??????? ????while?(curs.hasNext())?{ ???????????? ???System.out.println("query?result-------"?+?curs.next().get("_id").toString()); ??? ??????} ????????? ????//刪除集合中所有的數據 ?????? ?????DBObject?toRemoveObject?=?new?BasicDBObject(); ????? ??????dbObject.put("i",?0); ????????? ??coll.remove(toRemoveObject); ???????? ?????//刪除集合中某個文檔數據 ?????? ?????DBObject?toRemoveObject?=?new?BasicDBObject(); ??? ????????toRemoveObject.put("i",?5); ??????? ? ???DBObject?ob?=?coll.findOne(toRemoveObject); ???? ???????if?(ob?!=?null)?{ ?????????? ?????System.out.println("---to?remove-------"?+?ob); ???????? ???????coll.remove(ob); ?????? ?????} ??? ?//?????????coll.remove(new?BasicDBObject().append("i",?1)); ????????? ????//使用光標(cursor)來獲取當前集合中全部文檔 ?????? ?????DBCursor?cur?=?coll.find(); ????? ??????while?(cur.hasNext())?{ ??? ????????????System.out.println("------"?+?cur.next()); ? ??????????} ??????????? ??//為當前集合相應屬性創建索引,指定升序(1)或降序(-1)。 ??? ????????coll.createIndex(new?BasicDBObject("user",?1)); ??????? ??????//獲取索引列表 ???????? ???List<DBObject>?indexList?=?coll.getIndexInfo(); ??????? ????for?(DBObject?o?:?indexList)?{ ?????? ?????????System.out.println("index?---------"?+?o); ? ??????????} ?????????????//用DBObject存儲JAVA對象 ???? ???????DBCollection?collection?=?db.getCollection("MemberCollection"); ???? ???????//創建Java中的對象 ?????? ?????Member?member?=?new?Member(); ????? ??????member.put("userName",?"admin"); ????? ??????member.put("password",?"admin"); ?? ?????????member.put("logTime",?new?Date()); ???? ???????member.setUserName("admin"); ??? ????????member.setPassword("admin"); ???? ???????member.setLogTime(new?Date()); ??? ????????collection.insert(member); ?????? ???????//把文檔轉換成DBObject接口類型,要將它實例化為你的對象 ?? ?????????DBCollection.setObjectClass(); ????? ??????collection.setObjectClass(Member); ??? ????????Member?myTweet?=?(Member)?collection.findOne(); ??? ????????} ????? ? ??}???
轉載于:https://www.cnblogs.com/rq279/p/3912334.html
總結
- 上一篇: 【最小割】HDU 3987 Harry
- 下一篇: div+css相对定位和绝对定位