小白必须懂的MongoDB的十大总结
小白必須懂的MongoDB的總結(jié)
一、MongoDB的認(rèn)識
1、什么是MongoDB?
MongoDB 是一個(gè)介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的開源產(chǎn)品,是最接近于關(guān)系型數(shù)據(jù)庫的 NoSQL 數(shù)據(jù)庫。它在輕量級JSON 交換基礎(chǔ)之上進(jìn)行了擴(kuò)展,即稱為 BSON 的方式來描述其無結(jié)構(gòu)化的數(shù)據(jù)類型。盡管如此它同樣可以存儲(chǔ)較為復(fù)雜的數(shù)據(jù)類型。它和上一篇文章講到的Redis有異曲同工之妙。雖然兩者均為 NoSQL ,但是 MongoDB 相對于 Redis 而言,MongoDB 更像是傳統(tǒng)的數(shù)據(jù)庫。早些年我們是先有了 Relation Database (關(guān)系型數(shù)據(jù)庫),然后出現(xiàn)了很多很復(fù)雜的query ,里面用到了很多嵌套,很多 join 操作。所以在設(shè)計(jì)數(shù)據(jù)庫的時(shí)候,我們也考慮到了如何應(yīng)用他們的關(guān)系,使得寫 query 可以使 database 效率達(dá)到最高。后來人們發(fā)現(xiàn),不是每個(gè)系統(tǒng),都需要如此復(fù)雜的關(guān)系型數(shù)據(jù)庫。有些簡單的網(wǎng)站,比如博客,比如社交網(wǎng)站,完全可以斬?cái)鄶?shù)據(jù)庫之間的一切關(guān)系。這樣做帶來的好處是,設(shè)計(jì)數(shù)據(jù)庫變得更加簡單,寫 query 也變得更加簡單。然后,query 消耗的時(shí)間可能也會(huì)變少。因?yàn)?query 簡單了,少了許多消耗資源的 join 操作,速度自然會(huì)上去。正如所說的, query 簡單了,很有以前 MySQL 可以找到的東西,現(xiàn)在關(guān)系沒了,通過 Mongo 找不到了。我們只能將幾組數(shù)據(jù)都抓到本地,然后在本地做 join ,所以在這點(diǎn)上可能會(huì)消耗很多資源。這里我們可以發(fā)現(xiàn)。如何選擇數(shù)據(jù)庫,完全取決于你所需要處理的數(shù)據(jù)的模型,即 Data Model 。如果它們之間,關(guān)系錯(cuò)綜復(fù)雜,千絲萬縷,這個(gè)時(shí)候 MySQL 一定是首選。如果他們的關(guān)系并不是那么密切,那么, NoSQL 將會(huì)是利器。
MongoDB 和 Redis 一樣均為 key-value 存儲(chǔ)系統(tǒng),它具有以下特點(diǎn):
面向集合存儲(chǔ),易存儲(chǔ)對象類型的數(shù)據(jù)。
模式自由。
支持動(dòng)態(tài)查詢。
支持完全索引,包含內(nèi)部對象。
支持查詢。
支持復(fù)制和故障恢復(fù)。
使用高效的二進(jìn)制數(shù)據(jù)存儲(chǔ),包括大型對象(如視頻等)。
自動(dòng)處理碎片,以支持云計(jì)算層次的擴(kuò)展性
支持 Python , PHP , Ruby , Java , C , C# , Javascript ,Perl 及 C++ 語言的驅(qū)動(dòng)程序,社區(qū)中也提供了對 Erlang 及 .NET 等平臺(tái)的驅(qū)動(dòng)程序。
文件存儲(chǔ)格式為 BSON (一種 JSON 的擴(kuò)展)。
可通過網(wǎng)絡(luò)訪問。
2、MongoDB與MySQL性能比較
像 MySQL 一樣, MongoDB 提供了豐富的遠(yuǎn)遠(yuǎn)超出了簡單的鍵值存儲(chǔ)中提供的功能和功能。 MongoDB 具有查詢語言,功能強(qiáng)大的輔助索引(包括文本搜索和地理空間),數(shù)據(jù)分析功能強(qiáng)大的聚合框架等。相比使用關(guān)系數(shù)據(jù)庫而言,使用MongoDB ,您還可以使用如下表所示的這些功能,跨越更多樣化的數(shù)據(jù)類型和數(shù)據(jù)規(guī)模。
| 豐富的數(shù)據(jù)模型 | 否 | 是 |
| 動(dòng)態(tài) Schema | 否 | 是 |
| 數(shù)據(jù)類型 | 是 | 是 |
| 數(shù)據(jù)本地化 | 否 | 是 |
| 字段更新 | 是 | 是 |
| 易于編程 | 否 | 是 |
| 復(fù)雜事務(wù) | 是 | 否 |
| 審計(jì) | 是 | 是 |
| 自動(dòng)分片 | 否 | 是 |
MySQL 中的許多概念在 MongoDB 中具有相近的類比。本表概述了每個(gè)系統(tǒng)中的一些常見概念。
| 表 | 集合 |
| 行 | 文檔 |
| 列 | 字段 |
| joins | 嵌入文檔或者鏈接 |
3、應(yīng)用范圍和限制
MongoDB 的主要目標(biāo)是在 key-value (鍵/值)存儲(chǔ)方式(提供了高性能和高度伸縮性)以及傳統(tǒng)的 RDBMS 系統(tǒng)(豐富的功能)架起一座橋梁,集兩者的優(yōu)勢于一身。 MongoDB 適用范圍如下:
網(wǎng)站數(shù)據(jù): Mongo 非常適合實(shí)時(shí)的插入,更新與查詢,并具備網(wǎng)站實(shí)時(shí)數(shù)據(jù)存儲(chǔ)所需的復(fù)制及高度伸縮性。
緩存:由于性能很高, Mongo 也適合作為信息基礎(chǔ)設(shè)施的緩存層。在系統(tǒng)重啟之后,由 Mongo 搭建的持久化緩存層可以避免下層的數(shù)據(jù)源過載。
大尺寸,低價(jià)值的數(shù)據(jù):使用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫存儲(chǔ)一些數(shù)據(jù)時(shí)可能會(huì)比較昂貴,在此之前,很多時(shí)候程序員往往會(huì)選擇傳統(tǒng)的文件進(jìn)行存儲(chǔ)。
高伸縮性的場景: Mongo 非常適合由數(shù)十或數(shù)百臺(tái)服務(wù)器組成的數(shù)據(jù)庫。 Mongo 的路線圖中已經(jīng)包含對 MapReduce 引擎的內(nèi)置支持。
用于對象及 JSON 數(shù)據(jù)的存儲(chǔ): Mongo 的 BSON 數(shù)據(jù)格式非常適合文檔化格式的存儲(chǔ)及查詢。
MongoDB 當(dāng)然也會(huì)有以下場景的限制:
高度事物性的系統(tǒng):例如銀行或會(huì)計(jì)系統(tǒng)。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫目前還是更適用于需要大量原子性復(fù)雜事務(wù)的應(yīng)用程序。
傳統(tǒng)的商業(yè)智能應(yīng)用:針對特定問題的 BI 數(shù)據(jù)庫會(huì)對產(chǎn)生高度優(yōu)化的查詢方式。對于此類應(yīng)用,數(shù)據(jù)倉庫可能是更合適的選擇。
需要 SQL 的問題。
二、MongoDB的安裝
環(huán)境準(zhǔn)備
CentOS7
MongoDB 3.6
安裝步驟
1、創(chuàng)建一個(gè) mongodb-org-3.6.repo 文件
vi /etc/yum.repos.d/mongodb-org-3.6.repo在文件中加入如下內(nèi)容:
[mongodb-org-3.6] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.6/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-3.6.asc退出編輯模式,直接輸入如下命令安裝即可:
sudo yum install -y mongodb-org若要安裝特定版本的 MongoDB ,請分別指定每個(gè)組件包并將版本號附加到包名稱,如下所示:
sudo yum install -y mongodb-org-3.6.3 mongodb-org-server-3.6.3 mongodb-org-shell-3.6.3 mongodb-org-mongos-3.6.3 mongodb-org-tools-3.6.3你可以指定任何可用的 MongoDB 版本。然而, yum 會(huì)在新版本可用時(shí)升級軟件包。為防止意外升級,請釘住包裝。要固定軟件包,請將以下 exclude 指令添加到 /etc/yum.conf 文件中:
exclude=mongodb-org,mongodb-org-server,mongodb-org-shell,mongodb-org-mongos,mongodb-org-tools我們直接運(yùn)行如下命令:
mongod -repair看到如下字樣,說明我們安裝成功!
我們創(chuàng)建一個(gè) db ,并查看下 mongo 的安裝位置:
mkdir db whereis mongod安裝完成后啟動(dòng) mongodb ,并查看下 mongob 啟動(dòng)狀態(tài):
systemctl start mongod.service systemctl status mongod.service如果出現(xiàn)如下字樣,說明啟動(dòng)成功!
成功啟動(dòng) MongoDB 后,新建一個(gè)命令行輸入 mongo 進(jìn)行登錄操作,即可進(jìn)行數(shù)據(jù)庫的一些操作了。
mongo三、MongoDB數(shù)據(jù)類型及常用命令講解
MongoDB 的數(shù)據(jù)類型大致有下列幾種:
| String | 字符串。存儲(chǔ)數(shù)據(jù)常用的數(shù)據(jù)類型。在 MongoDB 中,UTF-8 編碼的字符串才是合法的。 |
| Integer | 整型數(shù)值。用于存儲(chǔ)數(shù)值。根據(jù)你所采用的服務(wù)器,可分為 32 位或 64 位。 |
| Boolean | 布爾值。用于存儲(chǔ)布爾值(真/假)。 |
| Double | 雙精度浮點(diǎn)值。用于存儲(chǔ)浮點(diǎn)值。 |
| Min/Max keys | 將一個(gè)值與 BSON (二進(jìn)制的 JSON)元素的最低值和最高值相對比。 |
| Arrays | 用于將數(shù)組或列表或多個(gè)值存儲(chǔ)為一個(gè)鍵。 |
| Timestamp | 時(shí)間戳。記錄文檔修改或添加的具體時(shí)間。 |
| Object | 用于內(nèi)嵌文檔。 |
| Null | 用于創(chuàng)建空值。 |
| Symbol | 符號。該數(shù)據(jù)類型基本上等同于字符串類型,但不同的是,它一般用于采用特殊符號類型的語言。 |
| Date | 日期時(shí)間。用 UNIX 時(shí)間格式來存儲(chǔ)當(dāng)前日期或時(shí)間。你可以指定自己的日期時(shí)間:創(chuàng)建 Date 對象,傳入年月日信息。 |
| Object ID | 對象 ID。用于創(chuàng)建文檔的 ID。 |
| Binary Data | 二進(jìn)制數(shù)據(jù)。用于存儲(chǔ)二進(jìn)制數(shù)據(jù)。 |
| Code | 代碼類型。用于在文檔中存儲(chǔ) JavaScript 代碼。 |
| Regular expression | 正則表達(dá)式類型。用于存儲(chǔ)正則表達(dá)式。 |
下面我們將介紹一些 MongoDB 的常用命令!
1、創(chuàng)建數(shù)據(jù)庫
use 數(shù)據(jù)庫名稱 :創(chuàng)建一個(gè)新的數(shù)據(jù)庫。注意:如果該數(shù)據(jù)庫不存在,則創(chuàng)建,如果該數(shù)據(jù)庫存在,則是切換
如果創(chuàng)建了數(shù)據(jù)庫,沒有任何的操作,則會(huì)自動(dòng)刪除該數(shù)據(jù)庫
example:
> use stu switched to db stu2、查看數(shù)據(jù)庫
show dbs :查看當(dāng)前有多少個(gè)數(shù)據(jù)庫
example:
> show dbs admin 0.000GB config 0.000GB local 0.000GB3、創(chuàng)建集合
db.集合名.insert({}) :向集合里面,添加文檔。{} 里面是 json 的文檔。注意: mongodb 里面的集合是隱式創(chuàng)建,就是無需創(chuàng)建,直接使用。 db 表示顯示當(dāng)前所在的數(shù)據(jù)庫。
example:
> db.php.insert({"name":"xiaoming","age":20,"email":"xiaoming@gmail.com"}) WriteResult({ "nInserted" : 1 }) > db.php.insert({"name":"xiaohong","age":18,"email":"xiaohong@gmail.com"}) WriteResult({ "nInserted" : 1 })4、查看集合
show tables :查看當(dāng)前數(shù)據(jù)庫中的集合
example:
> show tables php5、查詢集合里面的文檔
db.集合名.find() :查詢當(dāng)前數(shù)據(jù)庫中該集合下的所有文檔
example:
> db.php.find() { "_id" : ObjectId("5b9318ac487b851e62879578"), "name" : "xiaoming", "age" : 20, "email" : "xiaoming@gmail.com" } { "_id" : ObjectId("5b9319a2487b851e62879579"), "name" : "xiaohong", "age" : 18, "email" : "xiaohong@gmail.com" }db.集合名.find :查詢當(dāng)前數(shù)據(jù)庫中該集合下的第一個(gè)文檔
example:
> db.php.find function (query, fields, limit, skip, batchSize, options) {var cursor = new DBQuery(this._mongo,this._db,this,this._fullName,this._massageObject(query),fields,limit,skip,batchSize,options || this.getQueryOptions());{const session = this.getDB().getSession();const readPreference = session._serverSession.client.getReadPreference(session);if (readPreference !== null) {cursor.readPref(readPreference.mode, readPreference.tags);}const readConcern = session._serverSession.client.getReadConcern(session);if (readConcern !== null) {cursor.readConcern(readConcern.level);}}return cursor; }6、刪除集合
db.集合名.drop() :刪除當(dāng)前數(shù)據(jù)庫中的集合
example:
> db.php.drop() true7、刪除數(shù)據(jù)庫
db.dropDatabase() :刪除當(dāng)前的數(shù)據(jù)庫
> db.dropDatabase() { "dropped" : "stu", "ok" : 1 }8、幫助命令
help :全局幫助命令
> helpdb.help() help on db methodsdb.mycoll.help() help on collection methodssh.help() sharding helpersrs.help() replica set helpershelp admin administrative helphelp connect connecting to a db helphelp keys key shortcutshelp misc misc things to knowhelp mr mapreduceshow dbs show database namesshow collections show collections in current databaseshow users show users in current databaseshow profile show most recent system.profile entries with time >= 1msshow logs show the accessible logger namesshow log [name] prints out the last segment of log in memory, 'global' is defaultuse set current databasedb.foo.find() list objects in collection foodb.foo.find( { a : 1 } ) list objects in foo where a == 1it result of the last line evaluated; use to further iterateDBQuery.shellBatchSize = x set default number of items to display on shellexit quit the mongo shelldb.help() :數(shù)據(jù)庫相關(guān)的幫助命令
example:
> 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 cursordb.auth(username, password)db.cloneDatabase(fromhost)db.commandHelp(name) returns the help for the commanddb.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 dbdb.dropDatabase()db.eval() - deprecateddb.fsyncLock() flush data to disk and lock server for backupsdb.fsyncUnlock() unlocks server following a db.fsyncLock()db.getCollection(cname) same as db['cname'] or db.cnamedb.getCollectionInfos([filter]) - returns a list that contains the names and options of the db's collectionsdb.getCollectionNames()db.getLastError() - just returns the err msg stringdb.getLastErrorObj() - return full status objectdb.getLogComponents()db.getMongo() get the server connection objectdb.getMongo().setSlaveOk() allow queries on a replication slave serverdb.getName()db.getPrevError()db.getProfilingLevel() - deprecateddb.getProfilingStatus() - returns if profiling is on and slow thresholddb.getReplicationInfo()db.getSiblingDB(name) get the db at the same server as this onedb.getWriteConcern() - returns the write concern used for any operations on this db, inherited from server object if setdb.hostInfo() get details about the server's hostdb.isMaster() check replica primary statusdb.killOp(opid) kills the current operation in the dbdb.listCommands() lists all the db commandsdb.loadServerScripts() loads all the scripts in db.system.jsdb.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,)db.setProfilingLevel(level,slowms) 0=off 1=slow 2=alldb.setWriteConcern() - sets the write concern for writes to the dbdb.unsetWriteConcern() - unsets the write concern for writes to the dbdb.setVerboseShell(flag) display extra information in shell outputdb.shutdownServer()db.stats()db.version() current version of the serverdb.集合名.help() :集合相關(guān)的幫助命令
example:
> db.php.help() DBCollection helpdb.php.find().help() - show DBCursor helpdb.php.bulkWrite( operations, ) - bulk execute write operations, optional parameters are: w, wtimeout, jdb.php.count( query = {}, ) - count the number of documents that matches the query, optional parameters are: limit, skip, hint, maxTimeMSdb.php.copyTo(newColl) - duplicates collection by copying all documents to newColl; no indexes are copied.db.php.convertToCapped(maxBytes) - calls {convertToCapped:'php', size:maxBytes}} commanddb.php.createIndex(keypattern[,options])db.php.createIndexes([keypatterns], )db.php.dataSize()db.php.deleteOne( filter, ) - delete first matching document, optional parameters are: w, wtimeout, jdb.php.deleteMany( filter, ) - delete all matching documents, optional parameters are: w, wtimeout, jdb.php.distinct( key, query, ) - e.g. db.php.distinct( 'x' ), optional parameters are: maxTimeMSdb.php.drop() drop the collectiondb.php.dropIndex(index) - e.g. db.php.dropIndex( "indexName" ) or db.php.dropIndex( { "indexKey" : 1 } )db.php.dropIndexes()db.php.ensureIndex(keypattern[,options]) - DEPRECATED, use createIndex() insteaddb.php.explain().help() - show explain helpdb.php.reIndex()db.php.find([query],[fields]) - query is an optional query filter. fields is optional set of fields to return.e.g. db.php.find( {x:77} , {name:1, x:1} )db.php.find(...).count()db.php.find(...).limit(n)db.php.find(...).skip(n)db.php.find(...).sort(...)db.php.findOne([query], [fields], [options], [readConcern])db.php.findOneAndDelete( filter, ) - delete first matching document, optional parameters are: projection, sort, maxTimeMSdb.php.findOneAndReplace( filter, replacement, ) - replace first matching document, optional parameters are: projection, sort, maxTimeMS, upsert, returnNewDocumentdb.php.findOneAndUpdate( filter, update, ) - update first matching document, optional parameters are: projection, sort, maxTimeMS, upsert, returnNewDocumentdb.php.getDB() get DB object associated with collectiondb.php.getPlanCache() get query plan cache associated with collectiondb.php.getIndexes()db.php.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )db.php.insert(obj)db.php.insertOne( obj, ) - insert a document, optional parameters are: w, wtimeout, jdb.php.insertMany( [objects], ) - insert multiple documents, optional parameters are: w, wtimeout, jdb.php.mapReduce( mapFunction , reduceFunction , )db.php.aggregate( [pipeline], ) - performs an aggregation on a collection; returns a cursordb.php.remove(query)db.php.replaceOne( filter, replacement, ) - replace the first matching document, optional parameters are: upsert, w, wtimeout, jdb.php.renameCollection( newName , ) renames the collection.db.php.runCommand( name , ) runs a db command with the given name where the first param is the collection namedb.php.save(obj)db.php.stats({scale: N, indexDetails: true/false, indexDetailsKey: , indexDetailsName: })db.php.storageSize() - includes free space allocated to this collectiondb.php.totalIndexSize() - size in bytes of all the indexesdb.php.totalSize() - storage allocated for all data and indexesdb.php.update( query, object[, upsert_bool, multi_bool] ) - instead of two flags, you can pass an object with fields: upsert, multidb.php.updateOne( filter, update, ) - update the first matching document, optional parameters are: upsert, w, wtimeout, jdb.php.updateMany( filter, update, ) - update all matching documents, optional parameters are: upsert, w, wtimeout, jdb.php.validate( ) - SLOWdb.php.getShardVersion() - only for use with shardingdb.php.getShardDistribution() - prints statistics about data distribution in the clusterdb.php.getSplitKeysForChunks( ) - calculates split points over all chunks and returns splitter functiondb.php.getWriteConcern() - returns the write concern used for any operations on this collection, inherited from server/db if setdb.php.setWriteConcern( ) - sets the write concern for writes to the collectiondb.php.unsetWriteConcern( ) - unsets the write concern for writes to the collectiondb.php.latencyStats() - display operation latency histograms for this collection四、增刪改查操作
1、添加文檔
db.集合名.insert({k1:v1,k2:v2...}) :向當(dāng)前數(shù)據(jù)庫的該集合下添加文檔
我們在添加文檔的時(shí)候有如下注意點(diǎn):
a) 文檔就是鍵值對,數(shù)據(jù)類型是 BSON 格式,支持的值更加豐富。 BSON 是 JSON 的擴(kuò)展,新增了諸如日期,浮點(diǎn)等 JSON 不支持的數(shù)據(jù)類型。
b) 在添加的文檔里面,都有一個(gè) '_id' 的鍵,值為對象類型 ObjectID ,在這里,我們解釋下 ObjectID 類型:
每個(gè)文檔都有一個(gè) _id 字段,并且同一集合中的 _id 值唯一,該字段可以是任意類型的數(shù)據(jù),默認(rèn)是一個(gè) ObjectID 對象。
ObjectID 對象數(shù)據(jù)組成:時(shí)間戳|機(jī)器碼|PID|計(jì)數(shù)器
_id 的鍵值我們可以自己輸入,但是不能重復(fù),但要注意的一點(diǎn)是在插入數(shù)據(jù)的時(shí)候,如果 _id 的值重復(fù)則會(huì)報(bào)錯(cuò)
c) 可以使用 js 代碼來完成批量插入文檔
example:
> for(var i=1;i<=10;i++){ ... db.php.insert({'name':'xiaobai'+i,'age':i,'email':'xiaobai'+i+'@gmail.com'}) ... } WriteResult({ "nInserted" : 1 }) > db.php.find() { "_id" : ObjectId("5b931b74a39e4f4842ba36b3"), "name" : "xiaoming", "age" : 20, "email" : "xiaoming@gmail.com" } { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaohong", "age" : 18, "email" : "xiaohong@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36b5"), "name" : "xiaobai1", "age" : 1, "email" : "xiaobai1@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36b6"), "name" : "xiaobai2", "age" : 2, "email" : "xiaobai2@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36b7"), "name" : "xiaobai3", "age" : 3, "email" : "xiaobai3@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36b8"), "name" : "xiaobai4", "age" : 4, "email" : "xiaobai4@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36b9"), "name" : "xiaobai5", "age" : 5, "email" : "xiaobai5@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaobai6", "age" : 6, "email" : "xiaobai6@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "xiaobai7@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "age" : 8, "email" : "xiaobai8@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "xiaobai9@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "age" : 10, "email" : "xiaobai10@gmail.com" }2、刪除文檔
db.集合名.remove{(條件)} :刪除當(dāng)前數(shù)據(jù)庫下指定集合中滿足條件的文檔(不寫條件則刪除所有的文檔)
example:
> db.php.remove({age:20}) WriteResult({ "nRemoved" : 1 }) > db.php.remove({age:{'$lt':6}}) WriteResult({ "nRemoved" : 5 }) > db.php.find() { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaohong", "age" : 18, "email" : "xiaohong@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaobai6", "age" : 6, "email" : "xiaobai6@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "xiaobai7@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "age" : 8, "email" : "xiaobai8@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "xiaobai9@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "age" : 10, "email" : "xiaobai10@gmail.com" }這里我們在刪除 php 集合中年齡小于6的文檔時(shí),我們使用了操作符來完成。
比較運(yùn)算符
| $gt | 大于 |
| $lt | 小于 |
| $gte | 大于等于 |
| $lte | 小于等于 |
| $exists | 存在與否 |
| $in | 包含 |
| $ne | 不等于 |
| $nin | 不包含 |
邏輯運(yùn)算符
| $exists | 存在與否 |
| $or | 或者 |
| $and | 并且 |
| $not | 不存在 |
| $mod | 求模 |
| $where | 位置 |
特別的 $exists: true 表示字段存在
排序 sort
| $asc | 升序 |
| $desc | 降序 |
3、更新文檔
更新文檔有兩種方式進(jìn)行修改
方法一、直接修改
db.集合名.update({條件},{新的文檔}) :修改當(dāng)前數(shù)據(jù)庫下指定集合中滿足條件的文檔信息
example:
> db.php.find() { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaohong", "age" : 18, "email" : "xiaohong@gmail.com" } > db.php.update({age:18},{name:'xiaobai5'}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.php.find() { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaobai5" }db.集合.update(條件,新文檔,是否新增,是否修改多條) :修改當(dāng)前數(shù)據(jù)庫下指定集合中滿足條件的文檔信息
是否新增:如果值是1(true)則沒有滿足條件的 則添加
是否修改多條:若值是1(true),如果滿足條件的有多個(gè)文檔 則都要修改
example:
> db.php.update({age:10},{name:'xiaoli'},true,true) WriteResult({"nMatched" : 0,"nUpserted" : 0,"nModified" : 0,"writeError" : {"code" : 9,"errmsg" : "multi update only works with $ operators"} })方法二、使用修改器
example:
我們要修改 age=6 的文檔名稱為 xiaosan ,并且其他鍵值不能丟失
我們可以使用修改器
$inc :加上一個(gè)數(shù)字
$set :修改某一個(gè)字段,如果該字段不存在就增這個(gè)字段
語法:db.集合名.update({條件},{修改器名稱:{修改的鍵:修改的新值}})
> db.php.update({age:6},{'$set':{name:'xiaosan'}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })那如果我們要修改 age=10 的文檔的年齡增加十歲,我們可以這樣做:
> db.php.update({age:10},{$inc:{age:10}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })4、查詢文檔
語法: db.集合名.find({條件})
example:
取出 php 集合里面的第一個(gè)文檔
> db.php.findOne() { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaobai5" }取出 php 集合里面 age=6 的文檔
> db.php.find({age:6}) { "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaosan", "age" : 6, "email" : "xiaobai6@gmail.com" }取出 php 集合里面 age>8 的文檔
> db.php.find({age:{'$gt':8}}) { "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "xiaobai9@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "age" : 20, "email" : "xiaobai10@gmail.com" }取出 php 集合里面的文檔,只顯示 name 鍵
> db.php.find({},{age:1})//1表示只顯示age鍵值 { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4") } { "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "age" : 6 } { "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "age" : 7 } { "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "age" : 8 } { "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "age" : 9 } { "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "age" : 20 } > db.php.find({},{age:0})//1表示除了顯示age鍵值,其他的都顯示 { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaobai5" } { "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaosan", "email" : "xiaobai6@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "email" : "xiaobai7@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "email" : "xiaobai8@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "email" : "xiaobai9@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "email" : "xiaobai10@gmail.com" }根據(jù)年齡的(降序|升序)來顯示文檔
db.集合名.find().sort({age:1})根據(jù)年齡升序 db.集合名.find().sort({age:0})根據(jù)年齡降序顯示 php 集合中的前三個(gè)文檔
> db.php.find().limit(3) { "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaobai5" } { "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaosan", "age" : 6, "email" : "xiaobai6@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "xiaobai7@gmail.com" }顯示 php 集合中的第三個(gè)文檔到第五個(gè)文檔
> db.php.find().skip(2).limit(3) { "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "xiaobai7@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "age" : 8, "email" : "xiaobai8@gmail.com" } { "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "xiaobai9@gmail.com" }統(tǒng)計(jì) php 集合中文檔的個(gè)數(shù)
db.集合名.count():返回集合中有多少個(gè)文檔五、用戶管理(權(quán)限控制)
1、權(quán)限概述
在 MongoDB 里面的用戶是屬于數(shù)據(jù)庫的,每個(gè)數(shù)據(jù)庫都有自己的管理員。管理員登錄后,只能操作所屬的數(shù)據(jù)庫。注意:在 admin 的數(shù)據(jù)庫中創(chuàng)建的用戶是超級管理員,登陸后可以操作任何的數(shù)據(jù)庫
2、創(chuàng)建用戶
(1) 選擇數(shù)據(jù)庫
use 數(shù)據(jù)庫的名稱
(2) 添加用戶
db.createUser(用戶名,密碼,是否只讀)
第三個(gè)參數(shù)"是否只讀"默認(rèn)是 false ,創(chuàng)建的用戶可以執(zhí)行讀寫,如果是 true ,則創(chuàng)建的用戶只能查詢,不能修改。
注意點(diǎn):在創(chuàng)建用戶之前,必須先創(chuàng)建一個(gè)超級管理員
example:
> use admin switched to db admin > db.createUser({user:'user', ... pwd:'passwd', ... roles:[ ... {role:'userAdminAnyDatabase', db:'admin'} ... ] ... }) Successfully added user: {"user" : "user","roles" : [{"role" : "userAdminAnyDatabase","db" : "admin"}] }3、驗(yàn)證權(quán)限(用戶登錄)
在添加完成管理員之后,我們做如下操作:
(1) 如果你是安裝成windows服務(wù)的方式安裝的,則卸載服務(wù),在安裝時(shí)添加一個(gè) -auth 選項(xiàng),auth 表示要開啟權(quán)限認(rèn)證
(2) 如果你是直接啟動(dòng)的方式,則停止服務(wù),重新啟動(dòng),在啟動(dòng)時(shí)也要添加 --auth 選項(xiàng),auth 表示要開啟權(quán)限認(rèn)證
如果沒有通過權(quán)限驗(yàn)證,直接操作數(shù)據(jù)庫,則報(bào)如下錯(cuò)誤提示:
error: {"$err" : "unauthorized db:test lock type:-1 client:127.0.0.1","code" : 10057 }如何通過權(quán)限驗(yàn)證
選擇數(shù)據(jù)庫
執(zhí)行db.auth (用戶名,密碼)
4、刪除用戶和修改密碼
注意:創(chuàng)建的用戶名和密碼是存儲(chǔ)在各自數(shù)據(jù)庫里面的 system.users 集合里面的。想要?jiǎng)h除用戶,則直接刪除 system.users 集合里面的文檔即可
5、總結(jié)說明
a) 非 admin 數(shù)據(jù)庫的用戶不能使用數(shù)據(jù)庫命令,比如 show dbs 等
(b) admin 數(shù)據(jù)庫中的用戶被視為超級用戶(即管理員),在認(rèn)證之后,管理員可以讀寫所有數(shù)據(jù)庫,執(zhí)行特定的管理命令。
(c) 在開啟安全檢查之前,一定要至少有個(gè)管理員賬戶。
(d) 數(shù)據(jù)庫的用戶賬號以文檔的形式存儲(chǔ)在 system.users 集合里面。可以在 system.users 集合中刪除用戶賬號文檔,就可以刪除用戶。
六、MongoDB中的索引
1、普通單列索引
我們用如下代碼來測試:
for(var i=0;i<200000;i++){db.java.insert({name:'xiao'+i,age:i}) }第一、我們先檢驗(yàn)一下查詢性能
var start=new Date() db.java.find({name:'xiao156789'}) var end=new Date() end-start 17510第二、為 name 創(chuàng)建索引
> db.java.ensureIndex({name:1}) {"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1 }第三、再執(zhí)行第一部分代碼可以看出有數(shù)量級的性能提升
語法:db.集合名.ensureIndex({鍵名:1}) :1是升序,-1是降序
2、多列索引(復(fù)合索引)
創(chuàng)建多列索引
語法:db.集合名.ensureIndex({field1:1/-1,field2:1/-1})
對 name 和 age 建立一個(gè)復(fù)合索引,可以使用 db.集合名.getIndexes() 查看創(chuàng)建的索引情況
3、子文檔索引
語法: db.集合名.ensureIndex({field.subfield:1/-1})
如下文檔可以建立子文檔索引
比如要查詢 weight=100 的文檔
db.goods.find({'spc.weight':100})根據(jù)當(dāng)前案例,我們建立子文檔索引
db.net.ensureIndex({'spc.w':1})4、唯一索引
語法: db.集合名.ensureIndex({name:-1},{unique:true})
5、查看索引
(1) 查看當(dāng)前索引狀態(tài): db.集合名.getIndexes()
(2) 詳情查看本次查詢使用哪個(gè)索引和查詢數(shù)據(jù)的狀態(tài)信息: db.集合名.find({name:''xiao}).explain()
6、刪除索引
刪除單個(gè)索引: db.集合名.dropIndex({filed:1/-1})
刪除所有索引: db.集合名.dropIndexes()
7、重建索引
一個(gè)表經(jīng)過很多次修改后,導(dǎo)致表的文件產(chǎn)生空洞,索引文件也如此,可以通過索引的重建,減少索引文件碎片,并提高索引的效率,類似 mysql 中的 optimize table 。
mysql 里面使用 optimize table 語法: optimize table 表名
語法: db.集合名.reIndex()
8、索引使用注意事項(xiàng)
(1) 創(chuàng)建索引的時(shí)候,注意1是正序創(chuàng)建索引,-1是倒序創(chuàng)建索引
(2) 索引的創(chuàng)建在提高查詢性能的同時(shí)會(huì)影響插入性能,對于經(jīng)常查詢少插入
(3) 復(fù)合索引要注意索引的先后順序
(4) 每個(gè)鍵全建立索引不一定就能提高性能,索引不是萬能的。
(5) 在做排序工作的時(shí)候如果是超大數(shù)據(jù)量也可以考慮加上索引用來提高排序的性能。
八、MongoDB中的數(shù)據(jù)導(dǎo)出與導(dǎo)出
利用mongoexport
-h host主機(jī)
-port 端口
-d 指明使用的庫
-o 指明要導(dǎo)出的文件名
-csv 指定導(dǎo)出的csv格式
-q 過濾導(dǎo)出
-f field1 field2 列名
-u username 用戶名
-p password 密碼
注意:在使用用戶名和密碼是超級管理員的時(shí)候,如果端口是默認(rèn)的可以不使用-port來指定端口
(2) 導(dǎo)入數(shù)據(jù)
-d 待導(dǎo)入的數(shù)據(jù)庫
-c 待導(dǎo)入的集合(不存在會(huì)自己創(chuàng)建)
-type csv/json(默認(rèn))
-file 備份文件路徑
例如:導(dǎo)入json
./bin/mongoimport -h -port 端口號 -d test -c goods -file ./goodsall.json導(dǎo)入csv
./bin/mongoimport -h -port 端口號 -d test -c goods -type csv -f goods.id,goods.name -file ./goodsall.csv./bin/mongoimport -h -port 端口號 -d test -c goods -type csv -f -headline -f goods.id,goods.name -file ./goodsall.csv九、主從復(fù)制(讀寫分離)
主從復(fù)制是一個(gè)簡單的數(shù)據(jù)庫同步備份的集群技術(shù),至少兩臺(tái)數(shù)據(jù)庫服務(wù)器,可以分別設(shè)置主服務(wù)器和從服務(wù)器,對主服務(wù)器的任何操作都會(huì)同步到從服務(wù)器上。
實(shí)現(xiàn)的注意點(diǎn)
1、在數(shù)據(jù)庫集群中要明確的知道誰是主服務(wù)器,主服務(wù)器只有一臺(tái)
2、從服務(wù)器要知道自己的數(shù)據(jù)源 也就是對應(yīng)的主服務(wù)是誰
3、--master用來確定主服務(wù)器 --slave和--source來控制從服務(wù)器
配置步驟
(1) 啟動(dòng)主服務(wù)器
(2) 啟動(dòng)從服務(wù)器
(3) 客戶端登錄到主服務(wù)器
添加一些數(shù)據(jù),測試是否同步到從服務(wù)器,在主服務(wù)器里面,添加了一些文檔:
第一步,客戶端登錄到主服務(wù)器,添加一些文檔
第二步,登錄到從服務(wù)器,查看是否有數(shù)據(jù),如果有數(shù)據(jù),則成功了!
十、php操作MongoDB
1、安裝擴(kuò)展
注意:擴(kuò)展文件,下載合適的php_mongodb.dll文件
1) php的版本
2) 是否是線程安全的thread safe(ts)
3) 是vc幾的
4) php是32位的還是64位的
步驟
1) 把對應(yīng)的擴(kuò)展,拷貝到PHP的安裝目錄里面的ext目錄下面,注意:拷貝后改名為php_mongo.dll,方便管理
2) 打開php.ini文件,引入該擴(kuò)展
extension=php_mongo.dll3) 重啟Apache,使用phpinfo()函數(shù)測試
2、入門使用
1) 連接mongodb服務(wù)器
$m=new MongoClient("mongodb://root:root@localhost:8888/admin"); $db=$m->selectDb("stu");//選擇數(shù)據(jù)庫2) 增刪改查用法
增刪改查
注意,在命令行里面的"." 變成了"->","{}"變成了數(shù)組
a) 添加一個(gè)文檔
$db->php->insert(array('name'=>'李元霸','age'=>12));b) 查詢文檔
$data=$db->php->find();查詢年齡等于9的文檔:
$data=$db->php->find(array('age'=>9));查詢年齡大于9的文檔:
//db.php.find({age:{'$gt':9}}) $data=$db->php->find(array('age'=>array('$gt':9)));根據(jù)年齡降序顯示:
$data=$db->php->find()->sort(array('age'=>1)); foreach($data as $v){echo $v['name'].'----'.$v['age'].'--'.$v['email'].''; }c) 修改文檔,我們直接使用修改器來完成
把年齡等于8的名稱改名為李白:
//db.php.update({age:8},{'$set':{'name':'李白'}}) $db->php->update(array('age'=>8),array('$set'=>array('name'=>'李白'));d) 刪除文檔
比如刪除年齡等于10的文檔:
//db.php.remove({age:10}) $db->php->remove(array('age'=>10)) $data=$db->php->find() foreach($data as $v){echo $v['name'].'----'.$v['age'].'--'.$v['email'].''; }3) 把mysql表里面的數(shù)據(jù)存儲(chǔ)到mongodb里面
selectDb("stu");//選擇數(shù)據(jù)庫 //從mysql里面取出數(shù)據(jù) $conn=mysql_connect('localhost','root','root'); mysql_query('use shop'); mysql_query('set names utf8'); $sql="select * from goods"; $res=mysql_query($sql); while($row=mysql_fetch_assoc($res)){$db->goods->insert($row); } echo 'ok';轉(zhuǎn)載于:https://www.cnblogs.com/ECJTUACM-873284962/p/9613236.html
總結(jié)
以上是生活随笔為你收集整理的小白必须懂的MongoDB的十大总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdfs的常用命令
- 下一篇: 时速云入选2018中国企业服务创新成长5