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

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

Angel_Kittyphp

  •  

發表於小櫻的經驗隨筆訂閱html

1.7Kjava

在這篇文章中:

小白必須懂的MongoDB的總結

本文首發於imooc:https://www.imooc.com/article/75436mysql

1、MongoDB的認識

一、什麼是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 將會是利器。程序員

MongoDBRedis 同樣均爲 key-value 存儲系統,它具備如下特色:正則表達式

  • 面向集合存儲,易存儲對象類型的數據。
  • 模式自由。
  • 支持動態查詢。
  • 支持徹底索引,包含內部對象。
  • 支持查詢。
  • 支持複製和故障恢復。
  • 使用高效的二進制數據存儲,包括大型對象(如視頻等)。
  • 自動處理碎片,以支持雲計算層次的擴展性
  • 支持 PythonPHPRubyJavaCC#JavascriptPerlC++ 語言的驅動程序,社區中也提供了對 Erlang.NET 等平臺的驅動程序。
  • 文件存儲格式爲 BSON (一種 JSON 的擴展)。
  • 可經過網絡訪問。

二、MongoDB與MySQL性能比較

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

 

MySQLmongodb

MongoDBshell

豐富的數據模型數據庫

動態 Schema

數據類型

數據本地化

字段更新

易於編程

復瑣事務

審計

自動分片

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

MySQL

MongoDB

集合

文檔

字段

joins

嵌入文檔或者連接

三、應用範圍和限制

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

  • 網站數據: Mongo 很是適合實時的插入,更新與查詢,並具有網站實時數據存儲所需的複製及高度伸縮性。
  • 緩存:因爲性能很高, Mongo 也適合做爲信息基礎設施的緩存層。在系統重啓以後,由 Mongo 搭建的持久化緩存層能夠避免下層的數據源過載。
  • 大尺寸,低價值的數據:使用傳統的關係型數據庫存儲一些數據時可能會比較昂貴,在此以前,不少時候程序員每每會選擇傳統的文件進行存儲。
  • 高伸縮性的場景: Mongo 很是適合由數十或數百臺服務器組成的數據庫。 Mongo 的路線圖中已經包含對 MapReduce 引擎的內置支持。
  • 用於對象及 JSON 數據的存儲: MongoBSON 數據格式很是適合文檔化格式的存儲及查詢。

MongoDB 固然也會有如下場景的限制:

  • 高度事物性的系統:例如銀行或會計系統。傳統的關係型數據庫目前仍是更適用於須要大量原子性復瑣事務的應用程序。
  • 傳統的商業智能應用:針對特定問題的 BI 數據庫會對產生高度優化的查詢方式。對於此類應用,數據倉庫多是更合適的選擇。
  • 須要 SQL 的問題。

2、MongoDB的安裝

環境準備

安裝步驟

一、建立一個 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

若要安裝特定版本的 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

看到以下字樣,說明咱們安裝成功!

咱們建立一個 db ,並查看下 mongo 的安裝位置:

mkdir db
whereis mongod

安裝完成後啓動 mongodb ,並查看下 mongob 啓動狀態:

systemctl start mongod.service
systemctl status mongod.service

若是出現以下字樣,說明啓動成功!

成功啓動 MongoDB 後,新建一個命令行輸入 mongo 進行登陸操做,便可進行數據庫的一些操做了。

mongo

3、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 的經常使用命令!

一、建立數據庫

use 數據庫名稱 :建立一個新的數據庫。注意:若是該數據庫不存在,則建立,若是該數據庫存在,則是切換 若是建立了數據庫,沒有任何的操做,則會自動刪除該數據庫

example:

> use stu
switched to db stu

二、查看數據庫

show dbs :查看當前有多少個數據庫

example:

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

三、建立集合

db.集合名.insert({}) :向集合裏面,添加文檔。{} 裏面是 json 的文檔。注意: mongodb 裏面的集合是隱式建立,就是無需建立,直接使用。 db 表示顯示當前所在的數據庫。

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 })

四、查看集合

show tables :查看當前數據庫中的集合

example:

> show tables
php

五、查詢集合裏面的文檔

db.集合名.find() :查詢當前數據庫中該集合下的全部文檔

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 :查詢當前數據庫中該集合下的第一個文檔

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;
}

六、刪除集合

db.集合名.drop() :刪除當前數據庫中的集合

example:

> db.php.drop()
true

七、刪除數據庫

db.dropDatabase() :刪除當前的數據庫

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

八、幫助命令

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

4、增刪改查操做

一、添加文檔

db.集合名.insert({k1:v1,k2:v2...}) :向當前數據庫的該集合下添加文檔

咱們在添加文檔的時候有以下注意點:

a) 文檔就是鍵值對,數據類型是 BSON 格式,支持的值更加豐富。 BSONJSON 的擴展,新增了諸如日期,浮點等 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" : "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" }

二、刪除文檔

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" : "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的文檔時,咱們使用了操做符來完成。

比較運算符

操做符

效果

$gt

大於

$lt

小於

$gte

大於等於

$lte

小於等於

$exists

存在與否

$in

包含

$ne

不等於

$nin

不包含

邏輯運算符

操做符

效果

$exists

存在與否

$or

或者

$and

而且

$not

不存在

$mod

求模

$where

位置

特別的 $exists: true 表示字段存在

排序 sort

操做

效果

$asc

升序

$desc

降序

三、更新文檔

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

方法1、直接修改

db.集合名.update({條件},{新的文檔}) :修改當前數據庫下指定集合中知足條件的文檔信息

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(條件,新文檔,是否新增,是否修改多條) :修改當前數據庫下指定集合中知足條件的文檔信息

  • 是否新增:若是值是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"
    }
})

方法2、使用修改器

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 })

四、查詢文檔

語法: 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" : "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" }

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

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" : "xiaobai6@gmail.com" }
{ "_id" : ObjectId("5b931dfba39e4f4842ba36bb"), "name" : "xiaobai7", "age" : 7, "email" : "xiaobai7@gmail.com" }

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

> 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" }

統計 php 集合中文檔的個數

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

5、用戶管理(權限控制)

一、權限概述

MongoDB 裏面的用戶是屬於數據庫的,每一個數據庫都有本身的管理員。管理員登陸後,只能操做所屬的數據庫。注意:在 admin 的數據庫中建立的用戶是超級管理員,登錄後能夠操做任何的數據庫

二、建立用戶

(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"
        }
    ]
}

三、驗證權限(用戶登陸)

在添加完成管理員以後,咱們作以下操做:

(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 (用戶名,密碼)

四、刪除用戶和修改密碼

注意:建立的用戶名和密碼是存儲在各自數據庫裏面的 system.users 集合裏面的。想要刪除用戶,則直接刪除 system.users 集合裏面的文檔便可

五、總結說明

a) 非 admin 數據庫的用戶不能使用數據庫命令,好比 show dbs

(b) admin 數據庫中的用戶被視爲超級用戶(即管理員),在認證以後,管理員能夠讀寫全部數據庫,執行特定的管理命令。

(c) 在開啓安全檢查以前,必定要至少有個管理員帳戶。

(d) 數據庫的用戶帳號以文檔的形式存儲在 system.users 集合裏面。能夠在 system.users 集合中刪除用戶帳號文檔,就能夠刪除用戶。

6、MongoDB中的索引

一、普通單列索引

咱們用以下代碼來測試:

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

第1、咱們先檢驗一下查詢性能

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

第2、爲 name 建立索引

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

第3、再執行第一部分代碼能夠看出有數量級的性能提高

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

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

建立多列索引 語法:db.集合名.ensureIndex({field1:1/-1,field2:1/-1})nameage 創建一個複合索引,可使用 db.集合名.getIndexes() 查看建立的索引狀況

三、子文檔索引

語法: 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})

四、惟一索引

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

五、查看索引

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

(2) 詳情查看本次查詢使用哪一個索引和查詢數據的狀態信息: db.集合名.find({name:''xiao}).explain()

六、刪除索引

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

刪除全部索引: db.集合名.dropIndexes()

七、重建索引

一個表通過不少次修改後,致使表的文件產生空洞,索引文件也如此,能夠經過索引的重建,減小索引文件碎片,並提升索引的效率,相似 mysql 中的 optimize table

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

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

八、索引使用注意事項

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

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

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

(4) 每一個鍵全創建索引不必定就能提升性能,索引不是萬能的。

(5) 在作排序工做的時候若是是超大數據量也能夠考慮加上索引用來提升排序的性能。

8、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

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

主從複製是一個簡單的數據庫同步備份的集羣技術,至少兩臺數據庫服務器,能夠分別設置主服務器和從服務器,對主服務器的任何操做都會同步到從服務器上。

實現的注意點

一、在數據庫集羣中要明確的知道誰是主服務器,主服務器只有一臺

二、從服務器要知道本身的數據源 也就是對應的主服務是誰

三、--master用來肯定主服務器 --slave和--source來控制從服務器

配置步驟

(1) 啓動主服務器

(2) 啓動從服務器

(3) 客戶端登陸到主服務器

添加一些數據,測試是否同步到從服務器,在主服務器裏面,添加了一些文檔:

第一步,客戶端登陸到主服務器,添加一些文檔

第二步,登陸到從服務器,查看是否有數據,若是有數據,則成功了!

10、php操做MongoDB

一、安裝擴展

注意:擴展文件,下載合適的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

3) 重啓Apache,使用phpinfo()函數測試

二、入門使用

1) 鏈接mongodb服務器

$m=new MongoClient("mongodb://root:root@localhost:8888/admin");
$db=$m->selectDb("stu");//選擇數據庫

2) 增刪改查用法

增刪改查

注意,在命令行裏面的"." 變成了"->","{}"變成了數組

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'].'';
}

3) 把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';

本文參與騰訊雲自媒體分享計劃,歡迎正在閱讀的你也加入,一塊兒分享。

發表於 2018-09-21

MongoDBHTTP數據庫開源

相關文章
相關標籤/搜索