1. 程式人生 > >小白必須懂的MongoDB的十大總結

小白必須懂的MongoDB的十大總結

一、MongoDB的認識

1、什麼是 MongoDB ?

MongoDB 是一個介於關係資料庫和非關係資料庫之間的開源產品,是最接近於關係型資料庫的 NoSQL 資料庫。它在輕量級JSON 交換基礎之上進行了擴充套件,即稱為 BSON 的方式來描述其無結構化的資料型別。儘管如此它同樣可以儲存較為複雜的資料型別。它和上一篇文章講到的Redis有異曲同工之妙。雖然兩者均為 NoSQL ,但是 MongoDB 相對於 Redis 而言,MongoDB 更像是傳統的資料庫。早些年我們是先有了 Relation Database (關係型資料庫),然後出現了很多很複雜的query ,裡面用到了很多巢狀,很多 join

 操作。所以在設計資料庫的時候,我們也考慮到了如何應用他們的關係,使得寫 query 可以使 database 效率達到最高。後來人們發現,不是每個系統,都需要如此複雜的關係型資料庫。有些簡單的網站,比如部落格,比如社交網站,完全可以斬斷資料庫之間的一切關係。這樣做帶來的好處是,設計資料庫變得更加簡單,寫 query 也變得更加簡單。然後,query 消耗的時間可能也會變少。因為 query 簡單了,少了許多消耗資源的 join 操作,速度自然會上去。正如所說的, query 簡單了,很有以前 MySQL 可以找到的東西,現在關係沒了,通過 Mongo 找不到了。我們只能將幾組資料都抓到本地,然後在本地做 join
 ,所以在這點上可能會消耗很多資源。這裡我們可以發現。如何選擇資料庫,完全取決於你所需要處理的資料的模型,即 Data Model 。如果它們之間,關係錯綜複雜,千絲萬縷,這個時候 MySQL 一定是首選。如果他們的關係並不是那麼密切,那麼, NoSQL 將會是利器。

MongoDB 和 Redis 一樣均為 key-value 儲存系統,它具有以下特點:

  • 面向集合儲存,易儲存物件型別的資料。

  • 模式自由。

  • 支援動態查詢。

  • 支援完全索引,包含內部物件。

  • 支援查詢。

  • 支援複製和故障恢復。

  • 使用高效的二進位制資料儲存,包括大型物件(如視訊等)。

  • 自動處理碎片,以支援雲端計算層次的擴充套件性

  • 支援 Python , PHP , Ruby , Java , C , C# , Javascript ,Perl 及 C++ 語言的驅動程式,社群中也提供了對 Erlang 及 .NET 等平臺的驅動程式。

  • 檔案儲存格式為 BSON (一種 JSON 的擴充套件)。

  • 可通過網路訪問。

2、MongoDB 與 MySQL 效能比較

像 MySQL 一樣, MongoDB 提供了豐富的遠遠超出了簡單的鍵值儲存中提供的功能和功能。 MongoDB 具有查詢語言,功能強大的輔助索引(包括文字搜尋和地理空間),資料分析功能強大的聚合框架等。相比使用關係資料庫而言,使用MongoDB ,您還可以使用如下表所示的這些功能,跨越更多樣化的資料型別和資料規模。

MySQL MongoDB
豐富的資料模型
動態 Schema
資料型別
資料本地化
欄位更新
易於程式設計
複雜事務
審計
自動分片

MySQL 中的許多概念在 MongoDB 中具有相近的類比。本表概述了每個系統中的一些常見概念。

MySQL MongoDB
集合
文件
欄位
joins 嵌入文件或者連結

3、應用範圍和限制

MongoDB 的主要目標是在 key-value (鍵/值)儲存方式(提供了高效能和高度伸縮性)以及傳統的 RDBMS 系統(豐富的功能)架起一座橋樑,集兩者的優勢於一身。 MongoDB 適用範圍如下:

  • 網站資料: Mongo 非常適合實時的插入,更新與查詢,並具備網站實時資料儲存所需的複製及高度伸縮性。

  • **快取:**由於效能很高, Mongo 也適合作為資訊基礎設施的快取層。在系統重啟之後,由 Mongo 搭建的持久化快取層可以避免下層的資料來源過載。

  • **大尺寸,低價值的資料:**使用傳統的關係型資料庫儲存一些資料時可能會比較昂貴,在此之前,很多時候程式設計師往往會選擇傳統的檔案進行儲存。

  • 高伸縮性的場景: Mongo 非常適合由數十或數百臺伺服器組成的資料庫。 Mongo 的路線圖中已經包含對 MapReduce 引擎的內建支援。

  • 用於物件及 JSON 資料的儲存: Mongo 的 BSON 資料格式非常適合文件化格式的儲存及查詢。

MongoDB 當然也會有以下場景的限制:

  • 高度事物性的系統:例如銀行或會計系統。傳統的關係型資料庫目前還是更適用於需要大量原子性複雜事務的應用程式。

  • 傳統的商業智慧應用:針對特定問題的 BI 資料庫會對產生高度優化的查詢方式。對於此類應用,資料倉庫可能是更合適的選擇。

  • 需要 SQL 的問題。

二、MongoDB 的安裝

環境準備

安裝步驟

1、建立一個 mongodb-org-3.6.repo 檔案

vi /etc/yum.repos.d/mongodb-org-3.6.repo

在檔案中加入如下內容:

[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

C:Users87328DesktopMongoDB 若要安裝特定版本的 MongoDB ,請分別指定每個元件包並將版本號附加到包名稱,如下所示:

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 會在新版本可用時升級軟體包。為防止意外升級,請釘住包裝。要固定軟體包,請將以下 exclude 指令新增到 /etc/yum.conf 檔案中:

exclude=mongodb-org,mongodb-org-server,mongodb-org-shell,mongodb-org-mongos,mongodb-org-tools

我們直接執行如下命令:

mongod -repair

看到如下字樣,說明我們安裝成功!C:Users87328DesktopMongoDB 我們建立一個 db ,並檢視下 mongo 的安裝位置:C:Users87328DesktopMongoDB

mkdir db
whereis mongod

安裝完成後啟動 mongodb ,並檢視下 mongob 啟動狀態:

systemctl start mongod.service
systemctl status mongod.service

如果出現如下字樣,說明啟動成功!C:Users87328DesktopMongoDB 成功啟動 MongoDB 後,新建一個命令列輸入 mongo 進行登入操作,即可進行資料庫的一些操作了。

mongo

C:Users87328DesktopMongoDB

三、MongoDB 資料型別及常用命令講解

MongoDB 的資料型別大致有下列幾種:

資料型別 描述
String 字串。儲存資料常用的資料型別。在 MongoDB 中,UTF-8 編碼的字串才是合法的。
Integer 整型數值。用於儲存數值。根據你所採用的伺服器,可分為 32 位或 64 位。
Boolean 布林值。用於儲存布林值(真/假)。
Double 雙精度浮點值。用於儲存浮點值。
Min/Max keys 將一個值與 BSON (二進位制的 JSON)元素的最低值和最高值相對比。
Arrays 用於將陣列或列表或多個值儲存為一個鍵。
Timestamp 時間戳。記錄文件修改或新增的具體時間。
Object 用於內嵌文件。
Null 用於建立空值。
Symbol 符號。該資料型別基本上等同於字串型別,但不同的是,它一般用於採用特殊符號型別的語言。
Date 日期時間。用 UNIX 時間格式來儲存當前日期或時間。你可以指定自己的日期時間:建立 Date 物件,傳入年月日資訊。
Object ID 物件 ID。用於建立文件的 ID
Binary Data 二進位制資料。用於儲存二進位制資料。
Code 程式碼型別。用於在文件中儲存 JavaScript 程式碼。
Regular expression 正則表示式型別。用於儲存正則表示式。

下面我們將介紹一些 MongoDB 的常用命令!

1、建立資料庫

use 資料庫名稱 :建立一個新的資料庫。注意:如果該資料庫不存在,則建立,如果該資料庫存在,則是切換 如果建立了資料庫,沒有任何的操作,則會自動刪除該資料庫

example:

> use stu
switched to db stu

2、檢視資料庫

show dbs :檢視當前有多少個數據庫

example:

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

3、建立集合

db.集合名.insert({}) :向集合裡面,新增文件。{} 裡面是 json 的文件。注意: mongodb 裡面的集合是隱式建立,就是無需建立,直接使用。 db 表示顯示當前所在的資料庫。

example:

> db.php.insert({"name":"xiaoming","age":20,"email":"[email protected]"})
WriteResult({ "nInserted" : 1 })
> db.php.insert({"name":"xiaohong","age":18,"email":"[email protected]"})
WriteResult({ "nInserted" : 1 })

4、檢視集合

show tables :檢視當前資料庫中的集合

example:

> show tables
php

5、查詢集合裡面的文件

db.集合名.find() :查詢當前資料庫中該集合下的所有文件

example:

> db.php.find()
{ "_id" : ObjectId("5b9318ac487b851e62879578"), "name" : "xiaoming", "age" : 20, "email" : "[email protected]" }
{ "_id" : ObjectId("5b9319a2487b851e62879579"), "name" : "xiaohong", "age" : 18, "email" : "[email protected]" }

db.集合名.find :查詢當前資料庫中該集合下的第一個文件

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() :刪除當前資料庫中的集合

example:

> db.php.drop()
true

7、刪除資料庫

db.dropDatabase() :刪除當前的資料庫

> db.dropDatabase()
{ "dropped" : "stu", "ok" : 1 }

8、幫助命令

help :全域性幫助命令

> help
    db.help()                    help on db methods
    db.mycoll.help()             help on collection methods
    sh.help()                    sharding helpers
    rs.help()                    replica set helpers
    help admin                   administrative help
    help connect                 connecting to a db help
    help keys                    key shortcuts
    help misc                    misc things to know
    help mr                      mapreduce

    show dbs                     show database names
    show collections             show collections in current database
    show users                   show users in current database
    show profile                 show most recent system.profile entries with time >= 1ms
    show logs                    show the accessible logger names
    show log [name]              prints out the last segment of log in memory, 'global' is default
    use                 set current database
    db.foo.find()                list objects in collection foo
    db.foo.find( { a : 1 } )     list objects in foo where a == 1
    it                           result of the last line evaluated; use to further iterate
    DBQuery.shellBatchSize = x   set default number of items to display on shell
    exit                         quit the mongo shell

db.help() :資料庫相關的幫助命令

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 cursor
    db.auth(username, password)
    db.cloneDatabase(fromhost)
    db.commandHelp(name) returns the help for the command
    db.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 db
    db.dropDatabase()
    db.eval() - deprecated
    db.fsyncLock() flush data to disk and lock server for backups
    db.fsyncUnlock() unlocks server following a db.fsyncLock()
    db.getCollection(cname) same as db['cname'] or db.cname
    db.getCollectionInfos([filter]) - returns a list that contains the names and options of the db's collections
    db.getCollectionNames()
    db.getLastError() - just returns the err msg string
    db.getLastErrorObj() - return full status object
    db.getLogComponents()
    db.getMongo() get the server connection object
    db.getMongo().setSlaveOk() allow queries on a replication slave server
    db.getName()
    db.getPrevError()
    db.getProfilingLevel() - deprecated
    db.getProfilingStatus() - returns if profiling is on and slow threshold
    db.getReplicationInfo()
    db.getSiblingDB(name) get the db at the same server as this one
    db.getWriteConcern() - returns the write concern used for any operations on this db, inherited from server object if set
    db.hostInfo() get details about the server's host
    db.isMaster() check replica primary status
    db.killOp(opid) kills the current operation in the db
    db.listCommands() lists all the db commands
    db.loadServerScripts() loads all the scripts in db.system.js
    db.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=all
    db.setWriteConcern() - sets the write concern for writes to the db
    db.unsetWriteConcern() - unsets the write concern for writes to the db
    db.setVerboseShell(flag) display extra information in shell output
    db.shutdownServer()
    db.stats()
    db.version() current version of the server

db.集合名.help() :集合相關的幫助命令

example:

> db.php.help()
DBCollection help
    db.php.find().help() - show DBCursor help
    db.php.bulkWrite( operations,  ) - bulk execute write operations, optional parameters are: w, wtimeout, j
    db.php.count( query = {},  ) - count the number of documents that matches the query, optional parameters are: limit, skip, hint, maxTimeMS
    db.php.copyTo(newColl) - duplicates collection by copying all documents to newColl; no indexes are copied.
    db.php.convertToCapped(maxBytes) - calls {convertToCapped:'php', size:maxBytes}} command
    db.php.createIndex(keypattern[,options])
    db.php.createIndexes([keypatterns], )
    db.php.dataSize()
    db.php.deleteOne( filter,  ) - delete first matching document, optional parameters are: w, wtimeout, j
    db.php.deleteMany( filter,  ) - delete all matching documents, optional parameters are: w, wtimeout, j
    db.php.distinct( key, query,  ) - e.g. db.php.distinct( 'x' ), optional parameters are: maxTimeMS
    db.php.drop() drop the collection
    db.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() instead
    db.php.explain().help() - show explain help
    db.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, maxTimeMS
    db.php.findOneAndReplace( filter, replacement,  ) - replace first matching document, optional parameters are: projection, sort, maxTimeMS, upsert, returnNewDocument
    db.php.findOneAndUpdate( filter, update,  ) - update first matching document, optional parameters are: projection, sort, maxTimeMS, upsert, returnNewDocument
    db.php.getDB() get DB object associated with collection
    db.php.getPlanCache() get query plan cache associated with collection
    db.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, j
    db.php.insertMany( [objects],  ) - insert multiple documents, optional parameters are: w, wtimeout, j
    db.php.mapReduce( mapFunction , reduceFunction ,  )
    db.php.aggregate( [pipeline],  ) - performs an aggregation on a collection; returns a cursor
    db.php.remove(query)
    db.php.replaceOne( filter, replacement,  ) - replace the first matching document, optional parameters are: upsert, w, wtimeout, j
    db.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 name
    db.php.save(obj)
    db.php.stats({scale: N, indexDetails: true/false, indexDetailsKey: , indexDetailsName: })
    db.php.storageSize() - includes free space allocated to this collection
    db.php.totalIndexSize() - size in bytes of all the indexes
    db.php.totalSize() - storage allocated for all data and indexes
    db.php.update( query, object[, upsert_bool, multi_bool] ) - instead of two flags, you can pass an object with fields: upsert, multi
    db.php.updateOne( filter, update,  ) - update the first matching document, optional parameters are: upsert, w, wtimeout, j
    db.php.updateMany( filter, update,  ) - update all matching documents, optional parameters are: upsert, w, wtimeout, j
    db.php.validate(  ) - SLOW
    db.php.getShardVersion() - only for use with sharding
    db.php.getShardDistribution() - prints statistics about data distribution in the cluster
    db.php.getSplitKeysForChunks(  ) - calculates split points over all chunks and returns splitter function
    db.php.getWriteConcern() - returns the write concern used for any operations on this collection, inherited from server/db if set
    db.php.setWriteConcern(  ) - sets the write concern for writes to the collection
    db.php.unsetWriteConcern(  ) - unsets the write concern for writes to the collection
    db.php.latencyStats() - display operation latency histograms for this collection

四、增刪改查操作

1、新增文件

db.集合名.insert({k1:v1,k2:v2...}) :向當前資料庫的該集合下新增文件

我們在新增文件的時候有如下注意點:

a) 文件就是鍵值對,資料型別是 BSON 格式,支援的值更加豐富。 BSON 是 JSON 的擴充套件,新增了諸如日期,浮點等 JSON 不支援的資料型別。

b) 在新增的文件裡面,都有一個 '_id' 的鍵,值為物件型別 ObjectID ,在這裡,我們解釋下 ObjectID 型別:

每個文件都有一個 _id 欄位,並且同一集合中的 _id 值唯一,該欄位可以是任意型別的資料,預設是一個 ObjectID 物件。ObjectID 物件資料組成:時間戳|機器碼|PID|計數器_id 的鍵值我們可以自己輸入,但是不能重複,但要注意的一點是在插入資料的時候,如果 _id 的值重複則會報錯

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" : "[email protected]" }
{ "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaohong", "age" : 18, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36b5"), "name" : "xiaobai1", "age" : 1, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36b6"), "name" : "xiaobai2", "age" : 2, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36b7"), "name" : "xiaobai3", "age" : 3, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36b8"), "name" : "xiaobai4", "age" : 4, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36b9"), "name" : "xiaobai5", "age" : 5, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaobai6", "age" : 6, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "age" : 8, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "age" : 10, "email" : "[email protected]" }

2、刪除文件

db.集合名.remove{(條件)} :刪除當前資料庫下指定集合中滿足條件的文件(不寫條件則刪除所有的文件)

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" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaobai6", "age" : 6, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "age" : 8, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "age" : 10, "email" : "[email protected]" }

這裡我們在刪除 php 集合中年齡小於6的文件時,我們使用了操作符來完成。

比較運算子

操作符 效果
$gt 大於
$lt 小於
$gte 大於等於
$lte 小於等於
$exists 存在與否
$in 包含
$ne 不等於
$nin 不包含

邏輯運算子

操作符 效果
$exists 存在與否
$or 或者
$and 並且
$not 不存在
$mod 求模
$where 位置

特別的 $exists: true 表示欄位存在

排序 sort

操作 效果
$asc 升序
$desc 降序

3、更新文件

更新文件有兩種方式進行修改

方法一、直接修改

db.集合名.update({條件},{新的文件}) :修改當前資料庫下指定集合中滿足條件的文件資訊

example:

> db.php.find()
{ "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaohong", "age" : 18, "email" : "[email protected]" }
> db.php.update({age:18},{name:'xiaobai5'})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.php.find()
{ "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaobai5" }

db.集合.update(條件,新文件,是否新增,是否修改多條) :修改當前資料庫下指定集合中滿足條件的文件資訊

  • 是否新增:如果值是1(true)則沒有滿足條件的 則新增

  • 是否修改多條:若值是1(true),如果滿足條件的有多個文件 則都要修改

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 :加上一個數字

  • $set :修改某一個欄位,如果該欄位不存在就增這個欄位

語法: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 集合裡面的第一個文件

> db.php.findOne()
{ "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaobai5" }

取出 php 集合裡面 age=6 的文件

> db.php.find({age:6})
{ "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaosan", "age" : 6, "email" : "[email protected]" }

取出 php 集合裡面 age>8 的文件

> db.php.find({age:{'$gt':8}})
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "age" : 20, "email" : "[email protected]" }

取出 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" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36be"), "name" : "xiaobai10", "email" : "[email protected]" }

根據年齡的(降序|升序)來顯示文件

db.集合名.find().sort({age:1})根據年齡升序
db.集合名.find().sort({age:0})根據年齡降序

顯示 php 集合中的前三個文件

> db.php.find().limit(3)
{ "_id" : ObjectId("5b931b7ca39e4f4842ba36b4"), "name" : "xiaobai5" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36ba"), "name" : "xiaosan", "age" : 6, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "[email protected]" }

顯示 php 集合中的第三個文件到第五個文件

> db.php.find().skip(2).limit(3)
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bc"), "name" : "xiaobai8", "age" : 8, "email" : "[email protected]" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bd"), "name" : "xiaobai9", "age" : 9, "email" : "[email protected]" }

統計 php 集合中文件的個數

db.集合名.count():返回集合中有多少個文件

五、使用者管理(許可權控制)

1、許可權概述

在 MongoDB 裡面的使用者是屬於資料庫的,每個資料庫都有自己的管理員。管理員登入後,只能操作所屬的資料庫。注意:在 admin 的資料庫中建立的使用者是超級管理員,登陸後可以操作任何的資料庫

2、建立使用者

(1) 選擇資料庫

use 資料庫的名稱

(2) 新增使用者

db.createUser(使用者名稱,密碼,是否只讀)

第三個引數"是否只讀"預設是 false ,建立的使用者可以執行讀寫,如果是 true ,則建立的使用者只能查詢,不能修改。

注意點:在建立使用者之前,必須先建立一個超級管理員

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、驗證許可權(使用者登入)

在新增完成管理員之後,我們做如下操作:

(1) 如果你是安裝成windows服務的方式安裝的,則解除安裝服務,在安裝時新增一個 -auth 選項,auth 表示要開啟許可權認證

(2) 如果你是直接啟動的方式,則停止服務,重新啟動,在啟動時也要新增 --auth 選項,auth 表示要開啟許可權認證

如果沒有通過許可權驗證,直接操作資料庫,則報如下錯誤提示:

error: {
       "$err" : "unauthorized db:test lock type:-1 client:127.0.0.1",
        "code" : 10057
}

如何通過許可權驗證

  1. 選擇資料庫

  2. 執行db.auth (使用者名稱,密碼)

4、刪除使用者和修改密碼

注意:建立的使用者名稱和密碼是儲存在各自資料庫裡面的 system.users 集合裡面的。想要刪除使用者,則直接刪除 system.users 集合裡面的文件即可

5、總結說明

a) 非 admin 資料庫的使用者不能使用資料庫命令,比如 show dbs 等

(b) admin 資料庫中的使用者被視為超級使用者(即管理員),在認證之後,管理員可以讀寫所有資料庫,執行特定的管理命令。

© 在開啟安全檢查之前,一定要至少有個管理員賬戶。

(d) 資料庫的使用者賬號以文件的形式儲存在 system.users 集合裡面。可以在 system.users 集合中刪除使用者賬號文件,就可以刪除使用者。

六、MongoDB中的索引

1、普通單列索引

我們用如下程式碼來測試:

for(var i=0;i<200000;i++){
    db.java.insert({name:'xiao'+i,age:i})
}

第一、我們先檢驗一下查詢效能

var start=new Date()
db.java.find({name:'xiao156789'})
var end=new Date()
end-start
17510

第二、為 name 建立索引

> db.java.ensureIndex({name:1})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

第三、再執行第一部分程式碼可以看出有數量級的效能提升

語法:db.集合名.ensureIndex({鍵名:1}) :1是升序,-1是降序

2、多列索引(複合索引)

建立多列索引 語法:db.集合名.ensureIndex({field1:1/-1,field2:1/-1}) 對 name 和 age 建立一個複合索引,可以使用 db.集合名.getIndexes() 檢視建立的索引情況

3、子文件索引

語法: db.集合名.ensureIndex({field.subfield:1/-1}) 如下文件可以建立子文件索引

{name:'諾基亞手機1',price:12.34,spc:{weight:100,area:'紐約'}}
{name:'諾基亞手機2',price:42.34,spc:{weight:200,area:'倫敦'}}

比如要查詢 weight=100 的文件

db.goods.find({'spc.weight':100})

根據當前案例,我們建立子文件索引

db.net.ensureIndex({'spc.w':1})

4、唯一索引

語法: db.集合名.ensureIndex({name:-1},{unique:true})

5、檢視索引

(1) 檢視當前索引狀態: db.集合名.getIndexes()

(2) 詳情檢視本次查詢使用哪個索引和查詢資料的狀態資訊: db.集合名.find({name:''xiao}).explain()

6、刪除索引

刪除單個索引: db.集合名.dropIndex({filed:1/-1})

刪除所有索引: db.集合名.dropIndexes()

7、重建索引

一個表經過很多次修改後,導致表的檔案產生空洞,索引檔案也如此,可以通過索引的重建,減少索引檔案碎片,並提高索引的效率,類似 mysql 中的 optimize table 。

mysql 裡面使用 optimize table 語法: optimize table 表名

語法: db.集合名.reIndex()

8、索引使用注意事項

(1) 建立索引的時候,注意1是正序建立索引,-1是倒序建立索引

(2) 索引的建立在提高查詢效能的同時會影響插入效能,對於經常查詢少插入

(3) 複合索引要注意索引的先後順序

(4) 每個鍵全建立索引不一定就能提高效能,索引不是萬能的。

(5) 在做排序工作的時候如果是超大資料量也可以考慮加上索引用來提高排序的效能。

八、MongoDB中的資料匯出與匯出

利用mongoexport

  • -h host主機

  • -port 埠

  • -d 指明使用的庫

  • -o 指明要匯出的檔名

  • -csv 指定匯出的csv格式

  • -q 過濾匯出

  • -f field1 field2 列名

  • -u username 使用者名稱

  • -p password 密碼

注意:在使用使用者名稱和密碼是超級管理員的時候,如果埠是預設的可以不使用-port來指定埠

(2) 匯入資料

  • -d 待匯入的資料庫

  • -c 待匯入的集合(不存在會自己建立)

  • -type csv/json(預設)

  • -file 備份檔案路徑

例如:匯入json

./bin/mongoimport -h -port 埠號 -d test -c goods -file ./goodsall.json

匯入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

九、主從複製(讀寫分離)

主從複製是一個簡單的資料庫同步備份的叢集技術,至少兩臺資料庫伺服器,可以分別設定主伺服器和從伺服器,對主伺服器的任何操作都會同步到從伺服器上。C:Users87328DesktopMongoDB主從1C:Users87328DesktopMongoDB主從2 實現的注意點

1、在資料庫叢集中要明確的知道誰是主伺服器,主伺服器只有一臺

2、從伺服器要知道自己的資料來源 也就是對應的主服務是誰

3、–master用來確定主伺服器 --slave和–source來控制從伺服器

配置步驟

(1) 啟動主伺服器

(2) 啟動從伺服器

(3) 客戶端登入到主伺服器

新增一些資料,測試是否同步到從伺服器,在主伺服器裡面,添加了一些文件:

第一步,客戶端登入到主伺服器,新增一些文件

第二步,登入到從伺服器,檢視是否有資料,如果有資料,則成功了!

十、php操作MongoDB

1、安裝擴充套件

注意:擴充套件檔案,下載合適的php_mongodb.dll檔案

  1. php的版本

  2. 是否是執行緒安全的thread safe(ts)

  3. 是vc幾的

  4. php是32位的還是64位的

步驟

  1. 把對應的擴充套件,拷貝到PHP的安裝目錄裡面的ext目錄下面,注意:拷貝後改名為php_mongo.dll,方便管理

  2. 開啟php.ini檔案,引入該擴充套件

extension=php_mongo.dll
  1. 重啟Apache,使用phpinfo()函式測試

2、入門使用

  1. 連線mongodb伺服器
$m=new MongoClient("mongodb://root:[email protected]:8888/admin");
$db=$m->selectDb("stu");//選擇資料庫
  1. 增刪改查用法

增刪改查

注意,在命令列裡面的"." 變成了"->","{}"變成了陣列

a) 新增一個文件

$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)));

根據年齡降序顯示:

$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'].'';
}
  1. 把mysql表裡面的資料儲存到mongodb裡面
selectDb("stu");//選擇資料庫
//從mysql裡面取出資料
$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';