MongoDB筆記


0.json基本數據格式
 
JSON 對象在花括號中書寫:
{ "firstName":"John" , "lastName":"Doe" }

 

JSON 數組在方括號中書寫:

數組可包含多個對象:

 

{
    "employees": [
        { "firstName":"John" , "lastName":"Doe" },
        { "firstName":"Anna" , "lastName":"Smith" },
        { "firstName":"Peter" , "lastName":"Jones" }
    ]
}

在上面的例子中,對象 "employees" 是包含三個對象的數組。每個對象代表一條關於某人(有姓和名)的記錄。

 
 
 

1、安裝配置

下載解壓到目錄,新建data目錄存放數據庫,log存放日志
創建個配置文件mongodb.conf
port=10001
dbpath=/usr/lib64/mongodb/data/db
logpath=/usr/lib64/mongodb/data/log/mongodb.log
logappend=true
開啟server:./bin/mongod -f mongod.conf
開啟client:./bin/mongo  host:port
 

2、創建用戶

3.0版本
use admin
db.createUser({user:"yearnfar",pwd:"123456",roles:['root']})
修改密碼
db.changeUserPassword("username","newpassword")
查看用戶信息
db.runCommand({userInfo:"kangw"}) 
驗證用戶
db.auth("username","pwd")
 
 

3、與Mql對照

MySQL

MongoDB

說明

mysqld

mongod

服務器守護進程

mysql

mongo

客戶端工具

mysqldump

mongodump

邏輯備份工具

mysql

mongorestore

邏輯恢復工具

 

db.repairDatabase()

修復數據庫

mysqldump

mongoexport

數據導出工具

source

mongoimport

數據導入工具

grant * privileges on *.* to …

Db.addUser()【老版本】

Db.auth()

新建用戶並權限

show databases

show dbs

顯示庫列表

Show tables

Show collections

顯示表列表

Show slave status

Rs.status

查詢主從狀態

Create table users(a int, b int)

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

size:100000}) 另:可隱式創建表。

創建表

Create INDEX idxname ON users(name)

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

創建索引

Create INDEX idxname ON users(name,ts DESC)

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

創建索引

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

查詢表

Select * from users

db.users.find()

查詢表

Select * from users where age=33

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

條件查詢

Select a, b from users where age=33

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

條件查詢

select * from users where age<33

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

條件查詢

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

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

條件查詢


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

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

條件查詢

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

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

條件查詢

select * from users limit 1

db.users.findOne()

條件查詢

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

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

模糊查詢

select * from users where name like "Joe%"

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

模糊查詢

select count(1) from users

Db.users.count()

獲取表記錄數

select count(1) from users where age>30

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

獲取表記錄數

select DISTINCT last_name from users

db.users.distinct('last_name')

去掉重復值

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

獲取存儲路徑

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

刪除數據庫

drop table IF EXISTS test;

db.mytable.drop()

刪除表/collection

 

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

添加用戶

readOnly-->false

 

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

添加用戶

readOnly-->true

 

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

更改密碼

 

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

或者db.removeUser('test')

刪除用戶


 

use admin

超級用戶

 

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

用戶授權

 

db.system.users.find()

查看用戶列表

 

show users

查看所有用戶

 

db.printCollectionStats()

查看各collection的狀態

 

db.printReplicationInfo()

查看主從復制狀態

 

show profile

查看profiling

 

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

拷貝數據庫

 

db.users.dataSize()

查看collection數據的大小

 

db. users.totalIndexSize()

查詢索引的大小


4.插入數據
 

db.table.insert(....)  

 
db.table.insert({
    "name":"zhangsan",
    "age"   : 20,
    "like"   : [
        "apple","orange","phone"
    ]
})

5.update更新數據
db.collection.update(<query>,    <update>,{
     upsert:<boolean>,
     multi:<boolean>,
     writeConcern:<document>})

參數說明:

  • query : update的查詢條件,類似sql update查詢內where后面的。
  • update : update的對象和一些更新的操作符(如$,$inc...)等,也可以理解為sql update查詢內set后面的
  • upsert : 可選,這個參數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認是false,不插入。
  • multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數為true,就把按條件查出來多條記錄全部更新
  • writeConcern :可選,拋出異常的級別。

db.user.update(
    {
        "name":"zhangsan"        //where
    },
    {                                            //set age=age+2 , heigh=200
        $inc:{"age":2},                
        $set:{"heigh":200}
    },
    {                                               //更新符合條件的全部
        "multi":true
    }
)
 
 
save()方法,替換已有數據
db.collection.save(<document>,{
     writeConcern:<document>})
db.col.save({"_id":ObjectId("56064f89ade2f21f36b03136"),"title":"MongoDB","description":"MongoDB 是一個 Nosql 數據庫","by":"Runoob","url":"http://www.runoob.com","tags":["mongodb","NoSQL"],"likes":110})
 
         7.刪除數據 
        
db.collection.remove(<query>,<justOne>    //設置刪除的條數,沒有就是全部)
2.6版本后
db.collection.remove(<query>,{
     justOne:<boolean>,
     writeConcern:<document>})

參數說明:

  • query :(可選)刪除的文檔的條件。
  • justOne : (可選)如果設為 true 或 1,則只刪除一個文檔。
  • writeConcern :(可選)拋出異常的級別。
 
db.table.remove(
    {"name":"zhaosi"},        //where條件
    1                                    //只刪除1條,無則是全部
)
 
 
8.查詢數據
 
db.col.find({條件},{要獲取的字段})
db.col.find().pretty()
格式化顯示數據
db.col.findOne().pretty()
只顯示一條
 
mongodb中的內置關鍵變量
Conditional Operators :  $slice //切片
Conditional Operators :  $lt <,  $lte <=,  $gt >,  $gte >=
Conditional Operator :  $ne //不等於
Conditional Operator :  $in //屬於
Conditional Operator :  $nin //不屬於
Conditional Operator :  $mod //取模運算
Conditional Operator:    $all  //全部屬於
Conditional Operator :  $size //數量
Conditional Operator:  $exists //字段存在
Conditional Operator:  $type //字段類型
Conditional Operator:  $or // 或
Regular Expressions //正則表達式
Value in an Array // 數組中的值
Conditional Operator:  $elemMatch //要素符合
Value in an Embedded Object //內嵌對象中的值
Meta operator:  $not //不是
Javascript Expressions and  $where //
sort() //排序
limit() //限制取數據條數
skip() //跳過一定數值開始取
snapshot() //
count() // 數量
group() //分組
 
db.col.find({"by":"菜鳥教程","title":"MongoDB 教程"}).pretty()
WHERE by='菜鳥教程' AND title='MongoDB 教程'
 
db.col.find({$or:[{"by":"菜鳥教程"},{"title":"MongoDB 教程"}]}).pretty()
WHERE by='菜鳥教程' or title='MongoDB 教程'
 
db.col.find({"likes":{$gt:50}, $or:[{"by":"菜鳥教程"},{"title":"MongoDB 教程"}]}).pretty()
  'where likes>50 AND (by = '菜鳥教程' OR title = 'MongoDB 教程')'
 
db.col.find({likes :{$lt :200, $gt :100}})
 
        

Select*from col where likes>100 AND likes<200;

 
table.find({"name":{"$in":["abeen","ab","b"]}})
select * from table where name in (abeen,ab,b)
 
table.find({"age":{"$mod":[10,1]}})
查找age除10模等於1的
 
table.find({"name":{"$size": 6}}
取name元素數和$size數相同的信息

table.find({"name":{"$exists": True}}
取name存在的信息

table.find({"name":{"$type": 2}}
name類型為字符串的

type對應該類型表如下:


table.find({"name": {"$regex": r".*ee.*"}})
利用正則查詢

table.find({"info.name": "abeen"})
查找內部對象info的name等於abeen的信息


table.find({"$query" : {"name": "abeen"}, "$orderby": { "age": 1/-1 }})
select *from table where name="abeen" order by age asc/desc
$query - 查詢類似於sql中的 where
$orderby - 排序{x:1},1為升序 -1為降序

db.table.find().limit(10).skip(4)
select * from table limit 4,10
 

9.創建索引
db.table.ensureindex({key:1/-1}, {.其他選項} ,....,......);
1升序    -1降序
 
10.聚合
db.table.aggregate()



一、基礎

1.文檔
文檔是mongodb的核心概念,類型與關系型數據庫中的行。
多個鍵值有序的放置在一起便是文檔。
mongodb不但區分類型,也區分大小寫。
{  “foo":3   }
{    "foo":'3' }
{    "Foo":3  }
三個不同文檔
文檔中不能有重復的鍵
{    "Foo":3,“Foo":3  }
 
2.集合
集合就是一組文檔。類似關系型數據庫中的表
集合是無模式的,這意味着一個集合里面的文檔可以是各式各樣的。
{    "Foo":3  }
{    "Foo":3  ,“age":20}
 
3. db.getCollection("集合名稱")
獲取某個集合
db.getCollection("user").find()
 
因為某些集合的名稱是關鍵詞,或者是組合字符串得到的,可以用這個函數來操作
 
 
4.支持的數據類型              
null 
{"x":null}
布爾 
 {"x":true}
32位整數
shell中這個類型不可用,在js中僅支持64位浮點數,所以32位整數會被自動轉換
64位整數
 shell也不支持這個類型,shell會使用一個特殊的內嵌文檔來顯示64位整數。
64位浮點數
{"x":3.14},{"x":3}這個也是浮點數。shell中的數字都是這種類型的。
字符串
{"x":"xxxx"}
符號  
shell中也不支持這種類型,會把此轉換成字符串
對象id
 {"x":objectId()}
日期
{"x":new Date()}
正則表達式
{"x": /foobar/iU}
代碼
{"x": function(){ alert('a')}}
二進制數據
二進制數據可以由任意字節的串組成,不過shell中無法使用
最大值
bson包括一個特殊類型,表示可能的最大值
最小值
bson包括一個特殊類型,表示可能的最小值
未定義
{"x":undefined}
數組
{"x":["a","b"]}
內嵌別的文檔
{"x":{"foo":"bar"}}



5.修改
db.user.update({條件},{修改內容})
 
{ "_id" : ObjectId("5642ac0aca1b66a47448b8cf"), "name" : "zhangsan" }
 
5.1 //沒有變量修飾,會直接替換內容
db.user.update(
    {"name":"kang"},
    {"info":{"age":20}} 
)
{ "_id" : ObjectId("5642abecca1b66a47448b8ce"), "name" : "kangkang", "info" : { "age" : 22 } }
5.2//有系統變量
db.user.update(
    {"name":"kang"},
    { $set:{"age":20}}        //更新字段,如果鍵不存在,則創建它。
)
{ "_id" : ObjectId("5642ac0aca1b66a47448b8cf"), "name" : "zhangsan", "info" : { "age" : 22 } , "age" : 20}
 
5.2.1
db.user.update(
    {"name":"kang"},
    { $unset:{"age":1}}    //刪除指定的字段
)
{ "_id" : ObjectId("5642ac0aca1b66a47448b8cf"), "name" : "zhangsan", "info" : { "age" : 22 } }
 
5.2.2
$inc       字段自增
 
5.2.3
如果字段值為數組
db.user.update(
    {"name":"kang"},
    { $push:{"like":"apple"}}    //指定的鍵存在,則會向數組末尾加入一個元素。沒有則創建一個新的數組
)
db.user.update(
    {"name":"kang"},
    {$push:{"like":"orange"}}  
)
{ "_id" : ObjectId("5642ac0aca1b66a47448b8cf"), "name" : "zhangsan", "info" : { "age" : 22 }, "like":["apple","orange"] }
 
 
5.2.4
db.user.update(
    {"name":"kang"},
    { $addToSet:{"like":"apple"}}    //插入到數組中,存在則忽略,可以避免值出現重復
)
{ "_id" : ObjectId("5642ac0aca1b66a47448b8cf"), "name" : "zhangsan", "info" : { "age" : 22 }, "like":["apple","orange"] }


操作字段數組中的值,可以這樣db.user.update({"name":"kangkang"}, {$set:{" like.0","aaa"}})
定位符 $
 
 
6.查詢
 
db.user.find({條件},{要顯示的字段})
 
db.user.find({"name":"kang"}, {"age":1,"_id":0})
字段:值為1顯示
_id字段默認會顯示出來,值為0則不顯示
 
and查詢
db.user.find(
    {
        "age" : { "$gt":20 , "$lt":30 }
    }
)
where age>20 and age<30
 
in查詢
db.user.find(
    {
        "age": { "$in": [1,2,3,4] }
    }
)
where age in (1,2,3,4)
 
or查詢
db.user.find(
    {
        "$or":[  {"name":"kang"}, {"age":{"$lt":20}}  ]
    }
)
where  name="kang" or age<20
 
null匹配
null值不僅會匹配自身,如果其他條文檔(行)中不存在此字段,也會被匹配,所以在查詢的時候,還要判斷這個是否存在
db.user.find(
    {
        "from":{ "$in":[null],  "$exists":true }
    }
)
 
 
正則查詢
db.user.find(
    {
        "name":/kang/i        //i忽略大小寫
    }
)
 
數組查詢
{ "_id" : ObjectId("564590848cd6fe155ab16ac7"), "fruit" : [ "apple", "banana", "peach" ] }
{ "_id" : ObjectId("564591518cd6fe155ab16ac8"), "fruit" : [ "cherry", "orange", "apple" ] }
查詢有apple的
db.user.find(
    {
        "fruit":"apple"
    }
)
查詢有apple和banana
db.user.find({
    "fruit": {  "$all" : [ "apple","banana" ] }
})
查詢數組長度等於3的
db.user.find({
    "fruit": {  "$size" : 3 }
})
 
 
內嵌文檔查詢
db.comment.find().pretty()
{
    "_id" : ObjectId("5645978472a63ff99ddd6917"),
    "article" : 1,
    "comment" : [
        {
            "author" : "zhangsan",
            "score" : 1,
            "comment" : "zhangsanzhangsan"
        },
        {
            "author" : "zhaosi",
            "score" : 3,
            "comment" : "zhaosi44444"
        },
        {
            "author" : "zhaosi",
            "score" : 1,
            "comment" : "55555555555"
        },
        {
            "author" : "zhaosi",
            "score" : 2,
            "comment" : 6666666666666
        }
    ]
}
 
查author=zhangsan, score=1的評論
db.comment.find({"comment":{"$elemMatch":{"author":"zhangsan","score":1}}}).pretty()
 
 
skip().limit()
如果文檔很多,會導致速度很慢,因此可以使用sort().limit()代替
也就是說先排序,再limit
 
隨機獲取一條記錄
通常的做法:
先計算總條數,然后用隨機函數產生一個這個之間的數,再skip()取
現在可以在插入數據的時候,加一個隨機數的字段,然后用findOne()
 
高級查詢
 
普通查詢
    var    cursor = db.foo.find({"foo":"bar"}).sort({"age":-1})
     實際情況不是將{“foo”:"bar"}作為查詢直接發給數據庫,而是將查詢包裝在一個更大的文檔中。shell會把查詢從{“foo”:"bar"}轉換成
     {
         "$query"    :    {"foo":"bar"},
        "$orderby" :    {"age": -1}   
     }
 
 
 
索引
 
絕大多數,優化mysql索引的技巧也同樣適用於MongoDB
 
創建索引:
db.user.ensureIndex(
    {鍵:方向},
    {"name":索引名稱}
)
db.user.ensureIndex({"age":1,“year":-1},{"name":"age_year"})
對於同一個集合,同樣的索引只需要創建一次。反復創建是徒勞的
 
值為1或-1,與sort的作用一樣,指定方向,如果索引只有一個鍵,則方向無關緊要。
只有使用索引前部的查詢才能使用該索引。
 
為排序做索引
隨着集合的增長,需要針對查詢中大量的排序做索引,如果對沒有索引的鍵調用sort,MongoDB需要將所有數據提取到內存來排序,一旦集合大到不能再內存中排序,MongoDB就會報錯。
按照排序來索引以便讓MongoDB按照順序提取數據,這樣就能排序大規模數據,而不必擔心用光內存。
 
創建唯一索引
db.user.ensureIndex(
    {"name":1},
    {"unique":true}
)
 
如果插入了多個缺少該索引鍵的文檔,則由於文檔包含null值而導致插入失敗
當為已有的集合創建索引,可能有些值已經有重復了,那么索引創建失敗。
有時間希望將所有包含重復值的文檔都刪除掉。dropDups可以保留發現的第一個文檔,而刪除接下來的有重復值的文檔。
db.user.ensureIndex(
    {"name":1},
    {"unique":true, "dropDups":true},
    {"background" : true}
)
background 可以使這個過程在后台完成,同時正常處理請求,要是沒有,則數據庫會阻塞建立索引期間的所有請求。
 
刪除索引
db.runCommand(
    {"dropIndexes":表名},
    {"index":索引名稱}     //為*表示刪除全部索引
)
 
 
explain()分析
"cursor" : "BasiceCursor"
這說明查詢沒有使用索引
"nscanned":64
查了多少給文檔
"n":64
返回的文檔數量
"millis":0
毫秒數,查詢時間
 
 

聚合查詢
 
可以用來計算集合中文檔的個數,復雜的可以利用MapReduce做復雜數據分析
 
db.foo.count()
返回集合中的總條數
 
distinct
 
 
 
主從復制
 
1.最基本的設置方式建立一個主節點和多個從節點。
開啟主服務
    mongod   --dbpath  db/  --port 27001  --master
開啟從服務
    mongod    --dbpath db/  --port 27002  --slave  --source  127.0.0.1:27001
 
如果過多個節點對單個主節點發起查詢,會讓其吃不消,所以實際中,不超過12個從節點
 
2.選項:
    --only
    在從節點上指定只復制特定某個數據庫,默認復制所有的數據庫
 
    --slavedelay
    用在從節點上,設置同步主節點的時間周期,通過延緩執行操作,可以恢復誤刪的文件
 
    --autoresync
    如果從節點與主節點不同了,則自動同步
 
    --oplogSize
    主節點oplog的大小,單位MB
 
3.添加,刪除主源
  從節點啟動時,不添加主服務源地址,而是隨后添加
  啟動
    mongod    --dbpath     db/    --port    27002    --slave
添加源
    use    local
    db.sources.insert(  {"host":"127.0.0.1:27001"}  )   
  修改源,則可以用insert,remove來完成
    db.sources.insert( {"host":"prod.example.com:27001"} )
    db.sources.remove( {"host":"127.0.0.1:27001"} )
 
so  easy  !~~
 
 
副本集
開啟3台:
1/bin/mongod --dbpath=1/db/ --port=10001 --replSet=kang/127.0.0.1:10002
2/bin/mongod --dbpath=2/db/ --port=10002 --replSet=kang/127.0.0.1:10001
3/bin/mongod --dbpath=3/db/ --port=10003 --replSet=kang/127.0.0.1:10003
4/bin/mongod --dbpath=4/db/ --port=10004 --replSet=kang/127.0.0.1:10004
 
初始化副本集
隨便進入一台的admin集合中
mongo 127.0.0.1:10002/admin
初始化命令:
db.runCommand({
    "replSetInitiate":
      {
            "_id":"kang",
            "members":
              [
                   {"_id":1, "host":"127.0.0.1:10001"},
                    {"_id":2, "host":"127.0.0.1:10002"},
              ]
      }
})
再添加一台
rs.add("127.0.0.1:10003")
添加一台仲裁機
rs.addArb("127.0.0.1:10004")
 
仲裁機會把1,2,3中一台指定為主服務,其他的為副,如果主掛了,仲裁機會把副中的一台再指定為主,主重啟后變為副
 
在主從中,從服務是不能讀的,需要開啟rs.slaveOk(),從服務才可以讀,但是從是不能寫入的
 
 
分片







db.runCommand(
    {"addshard":"127.0.0.1:10001","allowLocal":true}
)





















免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM