Mongodb學習筆記

 

1、CentOS安裝mongodbjavascript

2、mongodb的三個元素html

3、Bson Typesjava

4、Sql與Mogondb對比linux

5、比較運算符git

6、邏輯運算符github

7、元素查詢運算符正則表達式

8、評估查詢運算符sql

9、數組查詢操做符mongodb

10、更新操做結構shell

11、字段更新操做符

12、數組更新

十3、位更新操做

十4、CURD 

十5、索引

十6、分佈式文件系統GridFS

十7、重量級聚合框架

十8、輕量級聚合框架group

十9、distinct

二10、mapReduce

二11、master-slave

二12、ReplicaSet集羣

二十3、mongodb分片(未完成)

二十4、驅動連接mongodb

 

1、CentOS安裝mongodb

1,下載並安裝mongodb

①下載地址:https://www.mongodb.com/download-center?jmp=nav#community

將下載的mongodb-linux-x86_64-3.6.2.tgz放置在centos的usr目錄下

網盤下載:https://pan.baidu.com/s/1c4dcdig

②解壓:mongodb-linux-x86_64-3.6.2.tgz

進入mongodb-linux-x86_64-3.6.2文件夾建立一個db文件夾

③啓動mongodb

命令:bin/mongod --dbpath=db

默認端口號:27017

2,下載並安裝robomongo可視化工具

①下載地址:https://robomongo.org/

網盤下載:https://pan.baidu.com/s/1oAl5kT0

 

3,鏈接mongodb服務器

mongodb客戶端一直鏈接不上centos的mongodb服務器
啓動mongodb服務須加上--bind_ip_all(例如:bin/mongod --dbpath=db --auth --bind_ip_all)

給mongodb服務器設置密碼:
①./mongo 鏈接mongodb服務器(./mongo --port 27017 -u "userAdmin" -p "123" --authenticationDatabase "admin")
②use admin 切換至admin數據庫
③db.createUser({user: "userAdmin",pwd: "123",roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]}) 建立管理員用戶,並指定其權限

 

2、mongodb的三個元素

mongodb   對應   sqlserver

database=》database

collection=》table

document=》row

1,基本操做

①建立database

②建立collection

③建立document

1,capped collection(固定集合)

①可視化設置固定集合

兩種存儲引擎:wiredtiger,mmap

②代碼建立固定集合

1)簡單建立固定集合

db.createCollection("log", { capped : true, size : 5242880, max : 5000 } )

2)複雜建立固定集合

db.createCollection(<name>,
 { capped: <boolean>,
    autoIndexId: <boolean>,
    size: <number>,
    max: <number>,
    storageEngine: <document>,
    validator: <document>,
    validationLevel: <string>,
    validationAction: <string>,
    indexOptionDefaults: <document> 
} )

3)將集合轉換爲固定集合

db.runCommand({"convertToCapped": "mycoll", size: 100000});

4)查看collection的狀態

db.log.stats()

5)倒序查詢

db.log.find().sort( { $natural: -1 } )

 

3、Bson Types

參考文檔:https://docs.mongodb.com/manual/reference/bson-types/

Type Number Alias Notes
Double 1 「double」  
String 2 「string」  
Object 3 「object」  
Array 4 「array」  
Binary data 5 「binData」  
Undefined 6 「undefined」 Deprecated.
ObjectId 7 「objectId」  
Boolean 8 「bool」  
Date 9 「date」  
Null 10 「null」  
Regular Expression 11 「regex」  
DBPointer 12 「dbPointer」 Deprecated.
JavaScript 13 「javascript」  
Symbol 14 「symbol」 Deprecated.
JavaScript (with scope) 15 「javascriptWithScope」  
32-bit integer 16 「int」  
Timestamp 17 「timestamp」  
64-bit integer 18 「long」  
Decimal128 19 「decimal」 New in version 3.4.
Min key -1 「minKey」  
Max key 127 「maxKey」  

1,經過find操做,用undefined作做爲比較條件

printjson(db.mycollection.find({"name":{$type:6}}).toArray());
printjson(db.mycollection.find({"name":{$type:'undefined'}}).toArray());

2,Timestamps

var a = new Timestamp();
db.test.insertOne( { ts: a } );

 

4、Sql與Mogondb對比

1,建立和更改表

SQL Mongodb
CREATE TABLE people ( id MEDIUMINT NOT NULL AUTO_INCREMENT, user_id Varchar(30), age Number, status char(1), PRIMARY KEY (id) )
db.people.insertOne( {  user_id: "abc123",  age: 55,  status: "A"  } )
或者
db.createCollection("people")
ALTER TABLE people ADD join_date DATETIME
 
db.people.updateMany(  { },  { $set: { join_date: new Date() } } )
ALTER TABLE people DROP COLUMN join_date
 
db.people.updateMany(  { },  { $unset: { "join_date": "" } } )
CREATE INDEX idx_user_id_asc ON people(user_id)
 db.people.createIndex( { user_id: 1 } )
CREATE INDEX idx_user_id_asc_age_desc ON people(user_id, age DESC)
 db.people.createIndex( { user_id: 1, age: -1 } )
DROP TABLE people
 db.people.drop()

2,插入數據

SQL Mongodb
INSERT INTO people(user_id, age, status) VALUES ("bcd001", 45, "A")
db.people.insertOne( { user_id: "bcd001", age: 45, status: "A" } )
 

3,查詢數據

 

SQL Mongodb
SELECT * FROM people
db.people.find()

 

SELECT id, user_id, status FROM people
 
db.people.find(  { },  { user_id: 1, status: 1 } )
SELECT user_id, status FROM people
 
db.people.find(  { },  { user_id: 1, status: 1, _id: 0 } )
SELECT * FROM people WHERE status = "A"
 
db.people.find(  { status: "A" } )
SELECT user_id, status FROM people WHERE status = "A"
 
db.people.find(  { status: "A" },  { user_id: 1, status: 1, _id: 0 } )
SELECT * FROM people WHERE status != "A"
 
db.people.find(  { status: { $ne: "A" } } )
SELECT * FROM people WHERE status = "A" AND age = 50
 
db.people.find(  { status: "A",  age: 50 } )
SELECT * FROM people WHERE status = "A" OR age = 50
 
db.people.find(  { $or: [ { status: "A" } ,  { age: 50 } ] } )
SELECT * FROM people WHERE age > 25
 
db.people.find(  { age: { $gt: 25 } } )
SELECT * FROM people WHERE age < 25
 
db.people.find(  { age: { $lt: 25 } } )
SELECT * FROM people WHERE age > 25 AND age <= 50
 
db.people.find(  { age: { $gt: 25, $lte: 50 } } )
SELECT * FROM people WHERE user_id like "%bc%"
 
db.people.find( { user_id: /bc/ } )
db.people.find( { user_id: { $regex: /bc/ } } )
SELECT * FROM people WHERE user_id like "bc%"
db.people.find( { user_id: /^bc/ } )
db.people.find( { user_id: { $regex: /^bc/ } } )
SELECT * FROM people WHERE status = "A" ORDER BY user_id ASC
 db.people.find( { status: "A" } ).sort( { user_id: 1 } )
SELECT * FROM people WHERE status = "A" ORDER BY user_id DESC
 db.people.find( { status: "A" } ).sort( { user_id: -1 } )
SELECT COUNT(*) FROM people
 
db.people.count()
db.people.find().count()
SELECT COUNT(user_id) FROM people
 
db.people.count( { user_id: { $exists: true } } )
db.people.find( { user_id: { $exists: true } } ).count()
SELECT COUNT(*) FROM people WHERE age > 30
 
db.people.count( { age: { $gt: 30 } } )
db.people.find( { age: { $gt: 30 } } ).count()
SELECT DISTINCT(status) FROM people
 
db.people.aggregate( [ { $group : { _id : "$status" } } ] )
db.people.distinct( "status" )
SELECT * FROM people LIMIT 1
 
db.people.findOne()
db.people.find().limit(1)
SELECT * FROM people LIMIT 5 SKIP 10
 db.people.find().limit(5).skip(10)
EXPLAIN SELECT * FROM people WHERE status = "A"
 db.people.find( { status: "A" } ).explain()

4,修改數據

SQL Mongodb
UPDATE people SET status = "C" WHERE age > 25
db.people.updateMany(  { age: { $gt: 25 } },  { $set: { status: "C" } } )
UPDATE people SET age = age + 3 WHERE status = "A"
 
db.people.updateMany(  { status: "A" } ,  { $inc: { age: 3 } } )

5,刪除數據

SQL Mongodb
DELETE FROM people WHERE status = "D"
db.people.deleteMany( { status: "D" } )
DELETE FROM people
 
db.people.deleteMany({})

 

5、比較運算符

比較運算符 備註 說明 用法
$eq = equal
{ <field>: { $eq: <value> } }
至關於field: <value> }
$gt > greater than {field: {$gt: value} }
$gte >= greater than equal {field: {$gte: value} }
$lt < less than
{field: {$lt: value} }
$lte <= less than equal field: $lte: value} }
$ne != not equal  {field: {$ne: value} }
$in in  
{ field: { $in: [<value1>, <value2>, ... <valueN> ] } }
$nin !in not in field: $nin: <value1>, <value2> ... <valueN> ]} }

1,測試數據

db.inventory.insert([
{ _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] },
{ _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] },
{ _id: 3, item: { name: "ij", code: "456" }, qty: 25, tags: [ "A", "B" ] },
{ _id: 4, item: { name: "xy", code: "456" }, qty: 30, tags: [ "B", "A" ] },
{ _id: 5, item: { name: "mn", code: "000" }, qty: 20, tags: [ [ "A", "B" ], "C" ] }])

2,案例

①查詢qty>=20的數據

db.inventory.find({"qty":{$gte:20}})

②查詢item對象中的name爲ab的數據

db.inventory.find({"item.name":{$eq:"ab"}})
db.inventory.find({"item.name":"ab"})

③查詢tags集合中包含C的數據

db.inventory.find({tags:{$in:["C"]}})

④查詢出tags集合爲[ [ "A", "B" ], "C" ]的數據

db.inventory.find({tags:{$eq:[["A","B"],"C"]}})

 

6、邏輯運算符

1,$and

①使用方法: { $and: [ { <expression1> }, { <expression2> } , ... , {<expressionN> } ] } 

②案例

db.inventory.find( { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } } ] } )
db.inventory.find( {
    $and : [
        { $or : [ { price : 0.99 }, { price : 1.99 } ] },
        { $or : [ { sale : true }, { qty : { $lt : 20 } } ] }
    ]
} )

2,$not

①使用方法:  { field: { $not: { <operator-expression> } } } 

②案例

db.inventory.find( { price: { $not: { $gt: 1.99 } } } )
db.inventory.find( { item: { $not: /^p.*/ } } )

3,$nor(or的反向)

①使用方法: { $nor: [ { <expression1> }, { <expression2> }, ... { <expressionN> } ] } 

②案例

db.inventory.find( { $nor: [ { price: 1.99 }, { sale: true } ]  } )
db.inventory.find( { $nor: [ { price: 1.99 }, { qty: { $lt: 20 } }, { sale: true } ] } )

4,$or

①使用方法: { $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] } 

②案例

db.inventory.find( { $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] } )

 

7、元素查詢運算符

1,$exists(判斷存不存在字段)

①使用方法: { field: { $exists: <boolean> } } 

②案例

db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )

2,$type

①使用方法: { field: { $type: <BSON type> } } 

②案例

db.addressBook.find( { "zipCode" : { $type : "number" } } )

 

8、評估查詢運算符

1,$expr【容許在查詢語言中使用聚合表達式。】

①使用方法: { $expr: { <expression> } } 

②案例

1)查詢花費大於預算

{ "_id" : 1, "category" : "food", "budget": 400, "spent": 450 }
{ "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 }
{ "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 }
{ "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 }
{ "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
數據
db.monthlyBudget.find({$expr:{$gt:[ "$spent","$budget" ]}})

2)qty>=100的狀況(price/2)<5;qty<100的狀況(price/4)<5

{ "_id" : 1, "item" : "binder", "qty": 100 , "price": 12 }
{ "_id" : 2, "item" : "notebook", "qty": 200 , "price": 8 }
{ "_id" : 3, "item" : "pencil", "qty": 50 , "price": 6 }
{ "_id" : 4, "item" : "eraser", "qty": 150 , "price": 3 }
supplies數據
db.supplies.find( {
    $expr: {
       $lt:[ {
          $cond: {
             if: { $gte: ["$qty", 100] },
             then: { $divide: ["$price", 2] },
             else: { $divide: ["$price", 4] }
           }
       },
       5 ] }
} )

2,$jsonSchema【根據給定的JSON模式驗證文檔】

①使用方法: { $jsonSchema: <schema> } 

參照文檔:https://docs.mongodb.com/manual/reference/operator/query/jsonSchema/#op._S_jsonSchema

3,$mod【取模運算】

①使用方法: { field: { $mod: [ 除數, 餘] } } 

②案例

{ "_id" : 1, "item" : "abc123", "qty" : 0 }
{ "_id" : 2, "item" : "xyz123", "qty" : 5 }
{ "_id" : 3, "item" : "ijk123", "qty" : 12 }
inventory數據

撈出qty除4餘0的數據

db.inventory.find( { qty: { $mod: [ 4, 0 ] } } )

3,$regex【選擇值與指定正則表達式匹配的文檔】

①使用方法: { <field>: /pattern/<options> } 

{ <field>: { $regex: /pattern/, $options: '<options>' } }
{ <field>: { $regex: 'pattern', $options: '<options>' } }
{ <field>: { $regex: /pattern/<options> } }
Option 描述 語法限制
i 不區分大小寫  
m

對於包含錨的模式(即起始爲^,結束爲$),在每行的開始或結束處匹配具備多行值的字符串。 沒有這個選項,這些錨點匹配字符串的開頭或結尾。 有關示例,請參閱多行匹配以指定模式開始的行。
若是模式不包含錨,或者字符串值沒有換行符(例如\ n),則m選項不起做用。

 
x

忽略$regex模式中的全部空格字符,除非轉義或包含在字符類中

須要使用$ options語法的$ regex
s 容許點字符匹配包括換行符的全部字符 須要使用$ options語法的$ regex

②案例

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }
{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }
{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before     line" }
{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }
products數據

查詢sku789結尾的數據(忽略大小寫)

db.products.find( { sku: { $regex: /789$/ } } )
db.products.find( { sku:/789$/i } )

4,$text【全文搜索。不支持中文】

①使用方法:

{
  $text:
    {
      $search: <string>,
      $language: <string>,
      $caseSensitive: <boolean>,
      $diacriticSensitive: <boolean>
    }
}

參考文檔:https://docs.mongodb.com/manual/reference/operator/query/text/#op._S_text

5,$where【匹配知足JavaScript表達式的文檔】

①案例

{
   _id: 12378,
   name: "Steve",
   username: "steveisawesome",
   first_login: "2017-01-01"
}
{
   _id: 2,
   name: "Anya",
   username: "anya",
   first_login: "2001-02-02"
}
users數據
db.foo.find( { $where: function() {
   return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994")
} } );

 

9、數組查詢操做符

1,$all【匹配包含查詢中指定的全部元素的數組】

①使用方法: { <field>: { $all: [ <value1> , <value2> ... ] } } 

②案例

{
   _id: ObjectId("5234cc89687ea597eabee675"),
   code: "xyz",
   tags: [ "school", "book", "bag", "headphone", "appliance" ],
   qty: [
          { size: "S", num: 10, color: "blue" },
          { size: "M", num: 45, color: "blue" },
          { size: "L", num: 100, color: "green" }
        ]
}

{
   _id: ObjectId("5234cc8a687ea597eabee676"),
   code: "abc",
   tags: [ "appliance", "school", "book" ],
   qty: [
          { size: "6", num: 100, color: "green" },
          { size: "6", num: 50, color: "blue" },
          { size: "8", num: 100, color: "brown" }
        ]
}

{
   _id: ObjectId("5234ccb7687ea597eabee677"),
   code: "efg",
   tags: [ "school", "book" ],
   qty: [
          { size: "S", num: 10, color: "blue" },
          { size: "M", num: 100, color: "blue" },
          { size: "L", num: 100, color: "green" }
        ]
}

{
   _id: ObjectId("52350353b2eff1353b349de9"),
   code: "ijk",
   tags: [ "electronics", "school" ],
   qty: [
          { size: "M", num: 100, color: "green" }
        ]
}
inventory數據

集合中包含"appliance", "school", "book" 的文檔

db.inventory.find( { tags: { $all: [ "appliance", "school", "book" ] } } )

 

2,$elemMatch【若是數組中的元素匹配全部指定的$ elemMatch條件,則選擇文檔】

①使用方法: { <field>: { $elemMatch: { <query1>, <query2>, ... } } } 

②案例

{ _id: 1, results: [ { product: "abc", score: 10 }, { product: "xyz", score: 5 } ] }
{ _id: 2, results: [ { product: "abc", score: 8 }, { product: "xyz", score: 7 } ] }
{ _id: 3, results: [ { product: "abc", score: 7 }, { product: "xyz", score: 8 } ] }
survey數據
db.survey.find(
   { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } }
)

 

3,$size【若是數組字段是指定的大小,則選擇文檔。】

db.collection.find( { field: { $size: 2 } } );

 

10、更新操做結構

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)
Parameter Type Description
query document

更新篩選條件

update document 修改
upsert boolean 可選的。 若是設置爲true,則在沒有文檔匹配查詢條件時建立一個新文檔。 默認值爲false,當找不到匹配項時不插入新文檔。
multi boolean 可選的。 若是設置爲true,則更新符合查詢條件的多個文檔。 若是設置爲false,則更新一個文檔。 默認值是false。 有關其餘信息,請參閱多參數。
writeConcern document

可選的。 表達寫入關注的文檔。 省略使用默認的寫入問題

collation document

可選的。

指定用於操做的排序規則。

整理容許用戶爲字符串比較指定特定於語言的規則

排序選項具備如下語法:

collation: { locale: <string>, caseLevel: <boolean>, caseFirst: <string>, strength: <int>, numericOrdering: <boolean>, alternate: <string>, maxVariable: <string>, backwards: <boolean> } 

指定排序規則時,語言環境字段是強制性的; 全部其餘整理字段是可選的。 有關這些字段的說明,請參閱整理文檔。

若是排序規則未指定,但該集合具備默認排序規則(請參閱db.createCollection()),則該操做使用爲該集合指定的排序規則。

若是沒有爲集合或操做指定排序規則,則MongoDB使用先前版本中使用的簡單二進制比較進行字符串比較。

您沒法爲操做指定多個歸類。 例如,不能爲每一個字段指定不一樣的排序規則,或者若是使用排序來執行查找,則不能使用一個排序規則查找,另外一個排序規則。

arrayFilters array

可選的。 一組過濾器文檔,用於肯定要修改陣列字段上的更新操做的數組元素。

在更新文檔中,使用$ [<identifier>]過濾位置運算符來定義標識符,而後在陣列過濾器文檔中引用該標識符。 若是標識符未包含在更新文檔中,則不能擁有標識符的數組篩選器文檔。

注意

<identifier>必須以小寫字母開頭,而且只包含字母數字字符。

您能夠在更新文檔中屢次包含相同的標識符; 可是,對於更新文檔中的每一個不一樣標識符($ [identifier]),必須正好指定一個相應的數組過濾器文檔。 也就是說,不能爲同一個標識符指定多個數組過濾器文檔。 例如,若是更新語句包含標識符x(可能屢次),則不能爲arrayFilters指定如下值:

[ { "x.a": { $gt: 85} }, { "x.b": { $gt: 80 } } ] 

可是,您能夠在單個數組過濾器文檔中的相同標識符上指定複合條件,例如:

[ { $or: [ { "x.a": { $gt: 85} }, { "x.b": { $gt: 80 } } ] } ] [ { $and: [ { "x.a": { $gt: 85} }, { "x.b": { $gt: 80 } } ] } ]

 

11、字段更新操做符

1,$currentDate【將字段的值設置爲當前日期,能夠是日期或時間戳】

①使用方法: { $currentDate: { <field1>: <typeSpecification1>, ... } } 

②案例

{ _id: 1, status: "a", lastModified: ISODate("2013-10-02T01:11:18.965Z") }
users數據
db.users.update({_id:2},{$currentDate:{lastModified:{ $type: "date" }}})

 

 

2,$inc【按指定的量增長字段的值】

①使用方法: { $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } } 

②案例

{
  _id: 1,
  sku: "abc123",
  quantity: 10,
  metrics: {
    orders: 2,
    ratings: 3.5
  }
}
products數據
db.products.update(
   { sku: "abc123" },
   { $inc: { quantity: -2, "metrics.orders": 1 } }
)

 

3,$min【若是指定的值小於現有字段值,則只更新字段】

①使用方法: { $min: { <field1>: <value1>, ... } } 

②案例

{ _id: 1, highScore: 800, lowScore: 200 }
scores數據

比原有lowScore的值小則更新

db.scores.update( { _id: 1 }, { $min: { lowScore: 150 } } )

 

4,$max【若是指定的值大於現有字段值,則只更新字段】

①使用方法: { $max: { <field1>: <value1>, ... } } 

②案例

{ _id: 1, highScore: 800, lowScore: 200 }
scores數據

比原有highScore的值大則更新

db.scores.update( { _id: 1 }, { $max: { highScore: 950 } } )

 

5,$mul【將字段的值乘以指定的數量】

①使用方法: { $mul: { field: <number> } } 

②案例

{ _id: 1, item: "ABC", price: 10.99 }

price值乘1.25

db.products.update(
   { _id: 1 },
   { $mul: { price: 1.25 } }
)

 

6,$rename【重命名一個字段】

①使用方法: {$rename: { <field1>: <newName1>, <field2>: <newName2>, ... } } 

②案例

db.students.updateMany( {}, { $rename: { "nmae": "name" } } )
db.students.update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )

 

7,$set【設置文檔中字段的值】

①使用方法: { $set: { <field1>: <value1>, ... } } 

②案例

{
  _id: 100,
  sku: "abc123",
  quantity: 250,
  instock: true,
  reorder: false,
  details: { model: "14Q2", make: "xyz" },
  tags: [ "apparel", "clothing" ],
  ratings: [ { by: "ijk", rating: 4 } ]
}
數據
db.products.update(
   { _id: 100 },
   { $set:
      {
        quantity: 500,
        details: { model: "14Q3", make: "xyz" },
        tags: [ "coats", "outerwear", "clothing" ]
      }
   }
)
db.products.update(
   { _id: 100 },
   { $set: { "details.make": "zzz" } }
)
db.products.update(
   { _id: 100 },
   { $set:
      {
        "tags.1": "rain gear",
        "ratings.0.rating": 2
      }
   }
)

 

8,$setOnInsert【若是更新致使插入文檔,則設置字段的值。 對修改現有文檔的更新操做沒有影響】

db.products.update(
  { _id: 1 },
  {
     $set: { item: "apple" },
     $setOnInsert: { defaultQty: 200 }
  },
  { upsert: true }
)

upsert: true表示沒有數據則插入;false表示沒有數據則什麼也不作
$setOnInsert: { defaultQty: 200 }表示只有插入時纔會將defaultQty設置爲 200。更新操做不會設置此值

 

9,$unset【從文檔中刪除指定的字段】

①使用方法: { $unset: { <field1>: "", ... } } 

②案例

db.products.update(
  { _id: 2 },
  {$unset:{item:""}}
)

 

12、數組更新

1,$ 【充當佔位符來更新匹配查詢條件的第一個元素】

①使用方法: { "<array>.$" : value } 

②案例

db.students.insert([
   { "_id" : 1, "grades" : [ 85, 80, 80 ] },
   { "_id" : 2, "grades" : [ 88, 90, 92 ] },
   { "_id" : 3, "grades" : [ 85, 100, 90 ] }
])
students數據

id爲1的項,將第一個grades爲80的項改成82

db.students.update(
   { _id: 1, grades: 80 },
   { $set: { "grades.$" : 82 } }
)

 

2,$[] 【充當佔位符來更新數組中與查詢條件匹配的全部元素】

①使用方法: { <update operator>: { "<array>.$[]" : value } } 

②案例

 id爲1的項,將grades全部項改成80

db.students.update(
   { _id: 1, grades: 82 },
   { $set: { "grades.$[]" : 80 } }
)

 

3,$[<identifier>] 【充當佔位符以更新與匹配查詢條件的文檔的arrayFilters條件匹配的全部元素】

①使用方法:

{ <update operator>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } } ] }

②案例

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 102 ] }
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
students數據
db.students.update(
   { },
   { $set: { "grades.$[element]" : 100 } },
   { multi: true,
     arrayFilters: [ { "element": { $gte: 100 } } ]
   }
)

 

4,$addToSet 【只有在數組中不存在元素的狀況下,才能將元素添加到數組中】

①使用方法: { $addToSet: { <field1>: <value1>, ... } } 

②案例

{ _id: 1, letters: ["a", "b"] }
test數據
db.test.update({_id:1},{$addToSet:{"letters":"e"}})
db.test.update({_id:1},{$addToSet:{"letters": {$each: [ "camera", "electronics", "accessories" ]}}})

 

5,$pop 【刪除數據中的最後一個或第一個】

①使用方法: { $pop: { <field>: <-1 | 1>, ... } } 

-1:彈出第一個;1:彈出最後一個

②案例

{
    "_id" : 1,
    "letters" : [ 
        "d", 
        "camera", 
        "electronics", 
        "accessories"
    ]
}
數據
db.test.update({_id:1},{$pop:{"letters":-1}})

 

6,$pull 【刪除全部匹配指定查詢的數組元素】

①使用方法: { $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } } 

②案例

{
   _id: 1,
   fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ],
   vegetables: [ "carrots", "celery", "squash", "carrots" ]
}
{
   _id: 2,
   fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ],
   vegetables: [ "broccoli", "zucchini", "carrots", "onions" ]
}
stores數據
db.stores.update(
    { },
    { $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } },
    { multi: true }
)
{
   _id: 1,
   results: [
      { item: "A", score: 5 },
      { item: "B", score: 8, comment: "Strongly agree" }
   ]
}
{
   _id: 2,
   results: [
      { item: "C", score: 8, comment: "Strongly agree" },
      { item: "B", score: 4 }
   ]
}
survey數據
db.survey.update(
  { },
  { $pull: { results: { score: 8 , item: "B" } } },
  { multi: true }
)


7,$push 【將一個項添加到數組中】

①使用方法: { $push: { <field1>: <value1>, ... } } 

Modifier Description
$each

將多個值附加到數組字段

$slice 限制數組元素的數量。 須要使用$ each修飾符。
$sort

排序 1:升序 -1:降序

$position

指定數組中插入新元素的位置。 須要使用$ each修飾符。 若是沒有$ position修飾符,$ push會將元素附加到數組的末尾。

②案例

db.students.update(
   { _id: 1 },
   {
     $push: {
       quizzes: {
         $each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ],
         $sort: { score: 1 }
       }
     }
   }
)
db.students.update(
   { _id: 2 },
   { $push: { tests: { $each: [ 40, 60 ], $sort: 1 } } }
)
db.students.update(
   { _id: 6 },
   {
     $push: {
       quizzes: {
          $each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
          $sort: { score: -1 },
          $slice: 2 //限制長度,多了會截取
       }
     }
   },
   {
       upsert:true}
)

 

8,$pullAll 【從數組中刪除全部匹配的值】

①使用方法: { $pullAll: { <field1>: [ <value1>, <value2> ... ], ... } } 

②案例

{ _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] }
survey數據
db.survey.update( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } )

 

9,$each【修改$push和$addToSet操做符以追加多個項目進行數組更新】

①使用方法:

{ $addToSet: { <field>: { $each: [ <value1>, <value2> ... ] } } }
{ $push: { <field>: { $each: [ <value1>, <value2> ... ] } } }

②案例

db.students.update(
   { name: "joe" },
   { $push: { scores: { $each: [ 90, 92, 85 ] } } }
)
db.inventory.update(
   { _id: 2 },
   { $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
 )

 

10,$position【修改$push操做符以指定數組中的位置以添加元素】

①使用方法:

{
  $push: {
    <field>: {
       $each: [ <value1>, <value2>, ... ],
       $position: <num>
    }
  }
}

②案例

{ "_id" : 1, "scores" : [ 100 ] }
students數據
db.students.update(
   { _id: 1 },
   {
     $push: {
        scores: {
           $each: [ 50, 60, 70 ],
           $position: 0
        }
     }
   }
)
{ "_id" : 1, "scores" : [  50,  60,  70,  100 ] }
顯示結果

 

11,$slice【修改$push操做符以限制更新數組的大小】

①使用方法:

{
  $push: {
     <field>: {
       $each: [ <value1>, <value2>, ... ],
       $slice: <num>
     }
  }
}
Value Description
0 將數組更新爲一個空數組([])
負數 保留數據最後一位,數組超出大小從左邊開始截取
正數

保留第一位,數組超出大小從右邊開始截取

②案例

1)將grades數組更新空數組

db.students.update(
   { _id: 1 },
   {
     $push: {
       grades: {
          $each: [ 1,2,4 ],
          $sort: { score: -1 },
          $slice: 0
       }
     }
   }
)

2)插入1,2,4 只會保留4

db.students.update(
   { _id: 1 },
   {
     $push: {
       grades: {
          $each: [ 1,2,4 ],
          $sort: { score: -1 },
          $slice: -1
       }
     }
   }
)

3)插入1,2,4 只會保留1

db.students.update(
   { _id: 1 },
   {
     $push: {
       grades: {
          $each: [ 1,2,4 ],
          $sort: { score: -1 },
          $slice:1
       }
     }
   }
)

 

12,$sort【修改$ push操做符以從新排列存儲在數組中的文檔】

①使用方法:

{
  $push: {
     <field>: {
       $each: [ <value1>, <value2>, ... ],
       $sort: <sort specification>
     }
  }
}

1指定爲升序,-1指定爲降序。

②案例

{
  "_id": 1,
  "quizzes": [
    { "id" : 1, "score" : 6 },
    { "id" : 2, "score" : 9 }
  ]
}
students數據
db.students.update(
   { _id: 1 },
   {
     $push: {
       quizzes: {
         $each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ],
         $sort: { score: 1 }
       }
     }
   }
)
{
  "_id" : 1,
  "quizzes" : [
     { "id" : 1, "score" : 6 },
     { "id" : 5, "score" : 6 },
     { "id" : 4, "score" : 7 },
     { "id" : 3, "score" : 8 },
     { "id" : 2, "score" : 9 }
  ]
}
結果
{ "_id" : 2, "tests" : [  89,  70,  89,  50 ] }
students數據
db.students.update(
   { _id: 2 },
   { $push: { tests: { $each: [ 40, 60 ], $sort: 1 } } }
)
{ "_id" : 2, "tests" : [  40,  50,  60,  70,  89,  89 ] }
結果
{ "_id" : 3, "tests" : [  89,  70,  100,  20 ] }
students數據
db.students.update(
   { _id: 3 },
   { $push: { tests: { $each: [ ], $sort: -1 } } }
)
{ "_id" : 3, "tests" : [ 100,  89,  70,  20 ] }
結果

 

十3、位更新操做

1,$bit【執行整數值的按位AND,OR和XOR更新。】

①使用方法: { $bit: { <field>: { <and|or|xor>: <int> } } } 

②案例

{ _id: 1, expdata: NumberInt(13) }

db.switches.update(
   { _id: 1 },
   { $bit: { expdata: { and: NumberInt(10) } } }
)

1101
1010
----
1000

{ "_id" : 1, "expdata" : 8 }
{ _id: 2, expdata: NumberLong(3) }

db.switches.update(
   { _id: 2 },
   { $bit: { expdata: { or: NumberInt(5) } } }
)

0011
0101
----
0111

{ "_id" : 2, "expdata" : NumberLong(7) }
{ _id: 3, expdata: NumberLong(1) }

db.switches.update(
   { _id: 3 },
   { $bit: { expdata: { xor: NumberInt(5) } } }
)

0001
0101
----
0100

{ "_id" : 3, "expdata" : NumberLong(4) }

 

十4、CURD 

1,Insert

1)db.collection.insertOne()【將單個文檔插入到一個集合中】

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.insertOne/#db.collection.insertOne

db.collection.insertOne(
   <document>,
   {
      writeConcern: <document>
   }
)

2)db.collection.insertMany()【將多個文檔插入到一個集合中】

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/#db.collection.insertMany

db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)

3)db.collection.insert()【將單個文檔或多個文檔插入到集合中】

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.insert/#db.collection.insert

db.collection.insert(
   <document or array of documents>,
   {
     writeConcern: <document>,
     ordered: <boolean>
   }
)

 

2,Query

1)查詢嵌入式/嵌套文檔

db.inventory.insertMany( [
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);
數據
db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )
db.inventory.find( { "size.uom": "in" } )
db.inventory.find( { "size.h": { $lt: 15 } } )
db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

2)查詢數組

db.inventory.insertMany([
   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },
   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },
   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },
   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },
   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }
]);
數據
db.inventory.find( { tags: ["red", "blank"] } )
db.inventory.find( { tags: { $all: ["red", "blank"] } } )
db.inventory.find( { tags: "red" } )
db.inventory.find( { dim_cm: { $gt: 25 } } )
db.inventory.find( { dim_cm: { $gt: 15, $lt: 20 } } )
db.inventory.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )
db.inventory.find( { "dim_cm.1": { $gt: 25 } } )
db.inventory.find( { "tags": { $size: 3 } } )

3)查詢嵌入式文檔數組

db.inventory.insertMany( [
   { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },
   { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },
   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },
   { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },
   { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
數據
db.inventory.find( { "instock": { warehouse: "A", qty: 5 } } )
db.inventory.find( { 'instock.qty': { $lte: 20 } } )
db.inventory.find( { 'instock.0.qty': { $lte: 20 } } )
db.inventory.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } ) 
db.inventory.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )
db.inventory.find( { "instock.qty": { $gt: 10,  $lte: 20 } } )
db.inventory.find( { "instock.qty": 5, "instock.warehouse": "A" } )

4)返回指定的字段

db.inventory.insertMany( [
  { item: "journal", status: "A", size: { h: 14, w: 21, uom: "cm" }, instock: [ { warehouse: "A", qty: 5 } ] },
  { item: "notebook", status: "A",  size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "C", qty: 5 } ] },
  { item: "paper", status: "D", size: { h: 8.5, w: 11, uom: "in" }, instock: [ { warehouse: "A", qty: 60 } ] },
  { item: "planner", status: "D", size: { h: 22.85, w: 30, uom: "cm" }, instock: [ { warehouse: "A", qty: 40 } ] },
  { item: "postcard", status: "A", size: { h: 10, w: 15.25, uom: "cm" }, instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }
]);
數據
db.inventory.find( { status: "A" }, { item: 1, status: 1 } )
SELECT _id, item, status from inventory WHERE status = "A"
db.inventory.find( { status: "A" }, { item: 1, status: 1, _id: 0 } )
SELECT item, status from inventory WHERE status = "A"

5)查詢空字段或缺乏字段

db.inventory.insertMany([
   { _id: 1, item: null },
   { _id: 2 }
])
數據
db.inventory.find( { item: null } )
db.inventory.find( { item : { $type: 10 } } )
db.inventory.find( { item : { $exists: false } } )

6)迭代遊標

var myCursor = db.users.find( { type: 2 } );

while (myCursor.hasNext()) {
   print(tojson(myCursor.next()));
}
var myCursor = db.users.find( { type: 2 } );

while (myCursor.hasNext()) {
   printjson(myCursor.next());
}
var myCursor =  db.users.find( { type: 2 } );

myCursor.forEach(printjson);
var myCursor = db.inventory.find( { type: 2 } );
var documentArray = myCursor.toArray();
var myDocument = documentArray[3];
var myCursor = db.users.find( { type: 2 } );
var myDocument = myCursor[1];

 

3,Update

1)db.collection.updateOne() 【即便多個文檔可能與指定的過濾器匹配,也會更新與指定過濾器匹配的單個文檔】
詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.updateOne/#db.collection.updateOne

db.collection.updateOne(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

 

2)db.collection.updateMany() 【更新全部匹配指定過濾器的文檔】

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.updateMany/#db.collection.updateMany

db.collection.updateMany(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

 

3)db.collection.replaceOne() 【即便多個文檔可能與指定的過濾器匹配,也只能替換與指定過濾器匹配的單個文檔】

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne/#db.collection.replaceOne

db.collection.replaceOne(
   <filter>,
   <replacement>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>
   }
)

 

4)db.collection.update()

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.update/#db.collection.update

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

更新或替換與指定過濾器匹配的單個文檔,或更新與指定過濾器匹配的全部文檔。

默認狀況下,db.collection.update()方法更新單個文檔。 要更新多個文檔,請使用multi選項。

 

4,Delete


1)db.collection.deleteOne() 【即便多個文檔可能匹配指定的過濾器,也最多刪除與指定過濾器匹配的單個文檔】

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.deleteOne/#db.collection.deleteOne

db.collection.deleteOne(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>
   }
)

 

2)db.collection.deleteMany() 【刪除全部匹配指定過濾器的文檔】

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.deleteMany/#db.collection.deleteMany

db.collection.deleteMany(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>
   }
)

 

3)db.collection.remove() 【刪除單個文檔或與指定過濾器匹配的全部文檔】.

詳細文檔:https://docs.mongodb.com/manual/reference/method/db.collection.remove/#db.collection.remove

db.collection.remove(
   <query>,
   <justOne>
)

justOne(true:刪除一個。false:刪除多個)。默認爲false

 

 

十5、索引

db.students.find({}).explain() //查詢執行計劃

1,Single Field Indexes(單鍵索引)

詳細文檔:https://docs.mongodb.com/manual/core/index-single/#create-an-index-on-an-embedded-field

1)在單個字段上建立升序索引

{
  "_id": ObjectId("570c04a4ad233577f97dc459"),
  "score": 1034,
  "location": { state: "NY", city: "New York" }
}
db.records.createIndex( { score: 1 } )

2)在嵌入式字段上建立索引

{
"_id": ObjectId("570c04a4ad233577f97dc459"),
"score": 1034,
"location": { state: "NY", city: "New York" }
}
db.records.createIndex( { "location.state": 1 } )

3)在嵌入式文檔上建立一個索引

{
"_id": ObjectId("570c04a4ad233577f97dc459"),
"score": 1034,
"location": { state: "NY", city: "New York" }
}
db.records.createIndex( { location: 1 } )

2,Compound Indexes(複合索引)

詳細文檔:https://docs.mongodb.com/manual/core/index-compound/

1)建立一個複合索引

{
"_id": ObjectId(...),
"item": "Banana",
"category": ["food", "produce", "grocery"],
"location": "4th Street Store",
"stock": 4,
"type": "cases"
}
db.products.createIndex( { "item": 1, "stock": 1 } )

3,Multikey Indexes(多鍵索引)

詳細文檔:https://docs.mongodb.com/manual/core/index-multikey/

要索引一個包含數組值的字段,MongoDB會爲數組中的每一個元素建立一個索引鍵

{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] }
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] }
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] }
{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] }
{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }

db.inventory.createIndex( { ratings: 1 } )

4,Hashed Indexes(hash索引)

詳細文檔:https://docs.mongodb.com/manual/core/index-hashed/

db.collection.createIndex( { _id: "hashed" } )

5,Partial Indexes(局部索引)

使用更小的空間提升部分性能

1)例如,如下操做將建立僅索引defaultQty字段大於200的文檔的複合索引。

db.products.createIndex({defaultQty:1},{ partialFilterExpression: { defaultQty: { $gt: 200 } } })

6,Unique Indexes(惟一索引)

db.members.createIndex( { "user_id": 1 }, { unique: true } )

7,Sparse Indexes(稀疏索引)

詳細文檔:https://docs.mongodb.com/manual/core/index-sparse/

即便索引字段包含空值,稀疏索引也只包含具備索引字段的文檔的條目。 索引跳過缺乏索引字段的任何文檔。 索引是「稀疏的」,由於它不包含集合的全部文檔。 相比之下,非稀疏索引包含集合中的全部文檔,爲那些不包含索引字段的文檔存儲空值。

1)建立一個稀疏索引(使用a做爲條件時會IXSCAN)

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "a" : "a" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "b" : "b" }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "c" : "c"}

db.scores.createIndex( { a: 1 } , { sparse: true } )

2)只查詢包含稀疏索引的字段(a)

db.getCollection('test').find().hint({ a: 1 })

結果:
/* 1 */
{
    "_id" : ObjectId("523b6e32fb408eea0eec2647"),
    "a" : "a"
}

 

8,TTL Indexes(過時索引)

詳細文檔:https://docs.mongodb.com/manual/core/index-ttl/

db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
expireAfterSeconds:過時秒數
注:mongodb每60s執行一次task。因此把過時時間設置的太短,也會60s執行一次
db.dates.insert({
    lastdate:new Date(),
    a:"a"
    })

db.dates.createIndex({"lastdate":1},{expireAfterSeconds:1})

 

十六,分佈式文件系統GridFS

1,什麼時候使用GridFS?

在MongoDB中,使用GridFS存儲大於16 MB的文件。 

2,GridFS集合

GridFS將文件存儲在兩個集合中:

  • chunks (fs.chunks)存儲二進制塊
  • files (fs.files)存儲文件的元數據
{
  "_id" : <ObjectId>,  //chunk的惟一ObjectId。
  "files_id" : <ObjectId>, //文件集合中指定的「父」文檔的_id。
  "n" : <num>, //chunk的序列號。 GridFS將全部chunk從0開始編號。
  "data" : <binary> //二進制
}
fs.chunks數據結構
{
  "_id" : <ObjectId>, //此文檔的惟一標識符
  "length" : <num>, //文檔的大小(以字節爲單位)
  "chunkSize" : <num>, //每一個塊的大小(以字節爲單位)默認大小是255千字節(kB)
  "uploadDate" : <timestamp>,//GridFS首次存儲文檔的日期
  "md5" : <hash>,//
  "filename" : <string>,//可選的。 GridFS文件的可讀名稱。
  "contentType" : <string>,//可選的。 GridFS文件的有效MIME類型。
  "aliases" : <string array>,//可選的。 一組別名字符串。
  "metadata" : <any>,//可選的。 元數據字段能夠是任何數據類型,而且能夠保存您想要存儲的任何附加信息
}
fs.files數據結構

3,這個 fs.chunks的索引

GridFS使用files_id和n字段在塊集合上使用惟一的複合索引。 這能夠有效地檢索塊,如如下示例所示:

db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )

若是此索引不存在,則能夠發出如下操做以使用mongo shell建立它:

db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );

4,這個 fs.files的索引

GridFS使用文件名和uploadDate字段在文件集合上使用索引。 這個索引容許高效地檢索文件,以下例所示:

db.fs.files.find( { filename: myFileName } ).sort( { uploadDate: 1 } )

若是此索引不存在,則能夠發出如下操做以使用mongo shell建立它:

db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );

6,使用mongofiles命令行工具上傳文件

詳細文檔:https://docs.mongodb.com/manual/reference/program/mongofiles/#bin.mongofiles

全部mongofiles命令都具備如下形式: mongofiles <options> <commands> <filename> 

mongofiles命令的組件是:

  1. Options. 您可使用一個或多個這些選項來控制mongofiles的行爲
  2. Commands. 使用這些命令之一來肯定mongofiles的操做
  3. 一個文件名,它能夠是:本地文件系統上的文件名稱,也能夠是GridFS對象.

1)案例

① 上傳文件

[root@localhost bin]# ./mongofiles -d test put ./sp.3gp

②查看test數據庫

 

 

十7、重量級聚合框架

參考文檔:https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/#db.collection.aggregate

注意:由於是管道執行,則須要注意執行順序

1,使用方式: db.collection.aggregate(pipeline, options)¶ 

pipeline:管道

options:可選的。 aggregate()傳遞給聚合命令的其餘選項。

管道:

Name Description
$addFields 將新字段添加到文檔。 輸出包含輸入文檔和新添加字段中全部現有字段的文檔。
$bucket 根據指定的表達式和存儲區邊界將傳入文檔分組到稱爲存儲桶的組中。
$bucketAuto 根據指定的表達式將傳入文檔分類到特定數量的組(稱爲存儲桶)。 桶邊界自動肯定,試圖將文檔均勻分佈到指定數量的桶中。
$collStats 返回有關集合或視圖的統計信息。
$count 返回聚合管道此階段的文檔數量。
$currentOp 返回有關MongoDB部署的活動和/或休眠操做的信息。 要運行,請使用db.aggregate()方法。
$facet 在同一組輸入文檔中的單個階段內處理多個聚合流水線。 支持建立多方面的聚合,可以在單個階段中跨多個維度或方面表徵數據。
$geoNear 根據地理空間點的接近度返回有序的文檔流。 包含地理空間數據的$ match,$ sort和$ limit功能。 輸出文件包含一個額外的距離字段,並可包含位置標識符字段。
$graphLookup 對集合執行遞歸搜索。 爲每一個輸出文檔添加一個新的數組字段,其中包含該文檔的遞歸搜索的遍歷結果。
$group 分組計算
$indexStats 查詢過程當中的索引狀況
$limit 返回制指定數量的文檔
$listLocalSessions 列出當前鏈接的mongos或mongodinstance上最近使用的全部活動會話。 這些會話可能還沒有傳播到system.sessions集合。
$listSessions 列出全部活動時間足以傳播到system.sessions集合的全部會話。
$lookup 錶鏈接
$match 至關於咱們的 where
$out 將最後的結果輸出到指定的collection中去
$project 至關於咱們sql操做的 select
$redact 根據存儲在文檔自己中的信息限制每一個文檔的內容,從新整形流中的每一個文檔。 包含$ project和$ match的功能。 可用於實施字段級別的編校。 對於每一個輸入文檔,輸出一個或零個文檔。
$replaceRoot 用指定的嵌入式文檔替換文檔。 該操做將替換輸入文檔中的全部現有字段,包括_id字段。 指定嵌入在輸入文檔中的文檔以將嵌入式文檔提高到頂層。
$sample 從其輸入中隨機選擇指定數量的文檔。
$skip 跳過前n個文檔
$sort 經過指定的排序鍵對文檔流進行從新排序。 只有訂單改變了; 文件保持不變。 對於每一個輸入文檔,輸出一個文檔。
$sortByCount 根據指定表達式的值對傳入文檔分組,而後計算每一個不一樣組中文檔的數量。
$unwind 將數據拆解成每個document

2,案例

①分組並計算amount的總和

{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }
orders 數據
db.orders.aggregate([
    {$match:{status:"A"}},
    {$group:{_id:"$cust_id",total:{$sum:"$amount"}}},
    {$sort:{total:-1}}
    ])

②返回①的執行計劃

db.orders.aggregate([
    {$match:{status:"A"}},
    {$group:{_id:"$cust_id",total:{$sum:"$amount"}}},
    {$sort:{total:-1}}
    ],
    {
        explain:true
     }
     )

③分頁

db.orders.aggregate([
    {$match:{status:"A"}},
    {$group:{_id:"$cust_id",total:{$sum:"$amount"}}},
    {$sort:{total:-1}},
    {$skip:1},//跳過一條
    {$limit:2}//返回兩條數據
    ])
db.orders.find().skip(0).limit(10)//普通分頁

③錶鏈接

db.orders.insert([
   { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 },
   { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 },
   { "_id" : 3  }
])
db.inventory.insert([
   { "_id" : 1, "sku" : "almonds", description: "product 1", "instock" : 120 },
   { "_id" : 2, "sku" : "bread", description: "product 2", "instock" : 80 },
   { "_id" : 3, "sku" : "cashews", description: "product 3", "instock" : 60 },
   { "_id" : 4, "sku" : "pecans", description: "product 4", "instock" : 70 },
   { "_id" : 5, "sku": null, description: "Incomplete" },
   { "_id" : 6 }
])
數據
db.orders.aggregate([
    {
        $lookup:{
            from:"inventory",
            localField:"item",
            foreignField:"sku",
            as:"inventory_docs"
        }
    }
])

 

十8、輕量級聚合框架group

詳細文檔:https://docs.mongodb.com/manual/reference/command/group/

使用方法:

{
  group:
   {
     ns: <namespace>,
     key: <key>,
     $reduce: <reduce function>,
     $keyf: <key function>,
     cond: <query>,
     finalize: <finalize function>
   }
}

ns:collections 你group的集合。。。

key: 咱們group的鍵值。。

$keyf: 採用函數的定義咱們的key, 咱們能夠後更高的靈活性來定義(去string的最後一個字母,或者中間,或者最後)

$reduce: 恰好就是咱們聚合進行中的每一個操做。。。

$initial: 聚合的初始文檔。。。

cond: ($match) where條件

finalize: 在某一個groupkey結束後插入點。。。。

1,案例:

{
    "_id" : 1,
    "sku" : "abc",
    "description" : "product 1",
    "instock" : 120
}
{
    "_id" : 2,
    "sku" : "def",
    "description" : "product 2",
    "instock" : 80
}
{
    "_id" : 3,
    "sku" : "ijk",
    "description" : "product 3",
    "instock" : 60
}
{
    "_id" : 4,
    "sku" : "jkl",
    "description" : "product 4",
    "instock" : 70
}
{
    "_id" : 5,
    "sku" : "abcedfe",
    "description" : "product 1",
    "instock" : 120
}

{
    "_id" : 6,
    "sku" : "def而微軟爲",
    "description" : "product 2",
    "instock" : 70
}
數據
db.runCommand(
   {
     group:
       {
         ns: 'test',
         key: { "description":1 },   //分組的key
         cond: { "_id":{$gt:1} },    //篩選條件
         $reduce: function ( curr, result ) {
            //curr:   當前當前獲得的document
            //result: 第一次就是咱們目前的initial,後續的話看你怎麼對result進行操做
                   result.count++;
            return result.total+=curr.instock;
         },
         initial: {"total":0,"count":0 },  //初始化文檔
         finalize:function(result){     //結束執行
            result.avg=result.total/result.count;
         }
       }
   }
)


db.runCommand(
   {
     group:
       {
         ns: 'test',
        //key: { "description":1 },   //分組的key
         $keyf:function(doc){
             return {"description":1}      //doc: 當前的文檔
          },
         cond: { "_id":{$gt:1} },
         $reduce: function ( curr, result ) {
            //curr:   當前當前獲得的document
            //result: 第一次就是咱們目前的initial,後續的話看你怎麼對result進行操做
                   result.count++;
            return result.total+=curr.instock;
         },
         initial: {"total":0,"count":0 },
         finalize:function(result){
            result.avg=result.total/result.count;
         }
       }
   }
)

 

十9、distinct

參考文檔:https://docs.mongodb.com/manual/reference/command/distinct/

使用方法:

{
  distinct: "<collection>",
  key: "<field>",
  query: <query>,
  readConcern: <read concern document>,
  collation: <collation document>
}

案例: db.runCommand ( { distinct: "test", key: "description" } ) 

 

二10、mapReduce

參考文檔:https://docs.mongodb.com/manual/reference/method/db.collection.mapReduce/index.html

使用方法:

db.collection.mapReduce(
                         <map>,
                         <reduce>,
                         {
                           out: <collection>,
                           query: <document>,
                           sort: <document>,
                           limit: <number>,
                           finalize: <function>,
                           scope: <document>,
                           jsMode: <boolean>,
                           verbose: <boolean>,
                           bypassDocumentValidation: <boolean>
                         }
                       )
Parameter Type Description
map function

一個JavaScript函數,該函數將一個值與一個鍵關聯或「映射」,併發出鍵和值對。

reduce function

一個JavaScript函數,它「減小」到一個對象,全部的值都與一個特定的鍵相關聯。

options document 其餘參數選項
bypassDocumentValidation boolean

可選的。容許mapReduce在操做過程當中繞過文檔驗證。這容許您插入不符合驗證要求的文檔。

 

Field Type Description
out string or document

指定map-reduce操做結果的位置。您能夠輸出到一個集合,輸出到一個具備動做的集合,或者內聯(inline)輸出。在對集合的主要成員執行map-reduce操做時,能夠輸出到集合;對於次要成員,您可能只使用內聯(inline)輸出。

query document 條件
sort document 排序
limit number 指定輸入到map函數的最大文檔數。
finalize function

可選的。遵循reduce方法並修改輸出

scope document 指定在映射中可訪問的全局變量,減小和肯定函數。
jsMode boolean

指定是否將中間數據轉換爲BSON格式,以執行映射和reduce函數。
默認值爲false。

If false:

  • 在內部,MongoDB將映射函數發出的JavaScript對象轉換爲BSON對象。當調用reduce函數時,這些BSON對象被轉換回JavaScript對象。
  • map-reduce操做將中間的BSON對象放在臨時的磁盤存儲中。這容許map-reduce操做執行任意大的數據集。

If true:

  • 在內部,map函數中發出的JavaScript對象仍然是JavaScript對象。不須要將對象轉換爲reduce函數,這會致使更快的執行。
  • 您只能使用少於500,000個不一樣關鍵參數的jsMode來得到mapper的emit()函數。
verbose boolean

指定是否在結果信息中包含計時信息。將verbose設置爲true,以包含計時信息。
默認值爲false。

collation document

可選的。
指定用於操做的排序規則。
Collation容許用戶爲字符串比較指定特定於語言的規則,好比字母大小寫和重音符號的規則。
collation選項有如下語法:

collation: { locale: <string>, caseLevel: <boolean>, caseFirst: <string>, strength: <int>, numericOrdering: <boolean>, alternate: <string>, maxVariable: <string>, backwards: <boolean> } 

在指定排序時,locale字段是強制的;全部其餘排序字段都是可選的。有關字段的描述,請參見Collation文檔。

若是排序未指定,可是集合有默認的排序規則(請參閱db.createCollection()),該操做將使用指定的排序集。
若是沒有爲集合或操做指定排序,MongoDB將使用之前版本中用於字符串比較的簡單二進制比較。
不能爲操做指定多個排序。例如,您不能指定每一個字段的不一樣排序,或者若是使用排序來執行查找,您不能使用一個排序來查找,而另外一個排序。
新的3.4版本中。

 

二11、master-slave

詳細文檔:https://docs.mongodb.com/manual/core/master-slave/

1,基礎搭建

①複製mongod程序到27000文件夾

②建立配置文件(1.config)

③建立db存儲文件夾

2,配置master config

port=27000
bind_ip=192.168.1.150
dbpath=./db
master=true

啓動mongodb: ./mongod --config 1.config 

3,配置slave config

port=27001
bind_ip=192.168.1.150
dbpath=./db
slave=true
source=192.168.1.150:27000

啓動mongodb: ./mongod --config 1.config 

4,其餘配置項

only:可選的。 指定數據庫的名稱。 指定時,MongoDB將只複製指定的數據庫。 

 

二12、ReplicaSet集羣

master掛掉其中一個secondary變爲master

 

arbiter:仲裁者沒有數據集的副本,也不能成爲主數據集。 副本組可能會有仲裁者在選舉主要增長一票。 仲裁者老是剛好1選投票,從而讓副本集有奇數表決權的成員

1,配置

port=27000 
bind_ip=192.168.1.150
dbpath=./db
replSet=test

2700一、2700二、27003配置文件差很少

2,啓動服務

./mongod --config 1.config

3,隨便連接一臺mongodb(例如連接192.168.1.150:27000)

添加集羣

rs.initiate()//初始化ReplicaSet集羣

rs.config()//查看配置信息

rs.status()//查看狀態

//向集羣中添加members
rs.add("192.168.1.150:27001")
rs.add("192.168.1.150:27002")

//添加仲裁
rs.addArb("192.168.1.150:27003")

 

二十3、mongodb分片(未完成)

1,配置

27000(mongos):

port=27000
bind_ip=192.168.1.150
configdb=192.168.1.150:27001

27001(config):

port=27001
bind_ip=192.168.1.150
dbpath=./db
configsvr=true

啓動: ./mongod --config 1.config 

27002:

27003:

3,步驟

①開啓config服務器

②開啓mongos服務器

 

二十4、驅動連接mongodb

參考文檔:http://mongodb.github.io/mongo-csharp-driver/2.2/getting_started/?jmp=docs&_ga=2.64367849.778289673.1521255001-1734184491.1516893909

nuget:MongoDB.Driver

    class Program
    {
        static void Main(string[] args)
        {
            // or use a connection string
            var client = new MongoClient("mongodb://192.168.1.150:27017");

            var db = client.GetDatabase("test");

            db.CreateCollection("aa");

        }
    }
相關文章
相關標籤/搜索