天天看點

MongoDB系列2——CRUD操作

CRUD操作

文章目錄

    • CRUD操作
      • 一、插入文檔
        • 1、insert增加單條資料
        • 2、insert增加多條資料
        • 3、insertOne插入一條資料
        • 4、InsertMany插入多條資料
      • 二、查詢文檔
        • 1、判斷符
        • 2、練習
          • 1、查詢status為A的文檔
          • 2、查詢status為P或D的文檔
          • 3、查詢status為A并且age小于30的文檔
          • 4、查詢status為A或者age小于30的文檔
          • 5、查詢status為A并且要麼age小于30要麼type為1的文檔
          • 6、嵌套文檔的精确查詢
          • 7、嵌套文檔中字段的等于比對
          • 8、數組中的精确比對
          • 9、比對數組中包含某個元素的文檔
          • 10、比對數組指定位置為某個值的元素
          • 11、`$elemMatch`查詢數組中至少有一個元素滿足所有指定條件的文檔
          • 11、元素組合滿足查詢條件
          • 12、使用數組指定索引比對嵌入文檔中的字段
          • 13、使用數組不指定索引比對嵌入文檔中的字段
          • 14、單個元素滿足條件
          • 15、元素組合滿足某個條件
        • 3、傳回查詢的映射字段
          • 1、映射文檔
          • 傳回比對文檔的所有字段
          • 隻傳回指定字段和`_id`字段
          • 隻傳回指定字段
          • 傳回排除字段之外的所有字段
          • 傳回嵌入文檔中的指定字段
          • 排除嵌入文檔中的特定字段
          • 映射數組中的嵌入文檔
          • 映射傳回數組中特定的數組元素(切片)
        • 4、查詢值為Null或不存在的字段
          • 相等過濾器
          • 類型篩選
          • 存在性篩選
        • 5、在mongo指令行中疊代遊标
          • 手動疊代遊标
          • 疊代器索引
          • Cursor Behaviors(遊标行為)
          • Cursor Information(光标資訊)
      • 三、更新文檔
        • 1、更新介紹
        • 2、行為表現
          • 1、原子性
          • 2、_id字段
          • 3、文檔大小
          • 4、字段順序
          • 5、upsert選項
        • 3、更新操作
          • 1、$set——修改指定字段
          • 2、$unset——删除某個列
          • 3、$rename——重命名某個列
          • 4、$inc——增加某個列
          • 5、選項:{upsert:true/false,multi:true/false}
      • 四、删除文檔
        • 1、删除的方法
        • 2、删除的行為表現
          • 1、索引
          • 2、原子性
        • 3、删除操作
        • 2、删除的行為表現
          • 1、索引
          • 2、原子性
        • 3、删除操作

一、插入文檔

插入文檔的方式共有三種,每一種的傳回值不同:

  • db.collection.insert()

  • db.collection.insertOne()

    3.2新增功能
  • db.collection.insertMany()

    3.2新增功能

MongoDB存儲的是文檔,文檔其實就是json對象。存儲于集合中的每一個文檔都需要一個唯一的_id字段作為primary_key。如果一個插入的文檔操作遺漏了_id字段,MongoDB驅動會自動為_id字段生成一個ObjectId。

1、insert增加單條資料

> db.man.insert({name:'youzi'})
WriteResult({ "nInserted" : 1 })
           

2、insert增加多條資料

> db.man.insert([{name:'zhangsan'},{name:'dachang'}])
BulkWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 2,
        "nUpserted" : 0,
        "nMatched" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})
           

3、insertOne插入一條資料

> db.man.insertOne({name:'xiaxia'})
{
        "acknowledged" : true,
        "insertedId" : ObjectId("5f0589da25bd42dbbb1469b4")
}
           

4、InsertMany插入多條資料

> db.man.insertMany([{name:'liuhuan'}])
{
        "acknowledged" : true,
        "insertedIds" : [
                ObjectId("5f0589fe25bd42dbbb1469b5")
        ]
}
           

二、查詢文檔

1、判斷符

MongoDB中提供了

db.collection.find()

方法從集合中讀取文檔。傳回指向比對文檔的:doc:cursor</tutorial/iterate-a-cursor>。

db.collection.find( <query filter> , <projection> )
           
判斷符 含義
name:‘zhangsan’ 相等
$gt:10 大于
$lt:10 小于
$gte:10 大于等于
$lte:10 小于等于
$ne:10 不等于
$nin:[1,2] 不在某個範圍内
$in:[1,2]
$and:[條件1,條件2] 并且
$or:[條件1,條件2]
$all:[20,30]

指定的資料都要有

db.collection.find({age:{$all:[‘lisi’]}})

$exists 是否存在某一列,1代表存在,0代表不存在。<br db.collection.find({name:{$exists:1}})
count()

統計數量

db.stu.find().count()

limit()

檢視指定數量的結果

db.collection.find().limit(4)

skip() db.collection.find().skip(4)

在相同字段執行等于查詢時,建議使用

$in

而不使用

$or

首先插入資料:

db.users.insertMany(
  [
     {
       _id: 1,
       name: "sue",
       age: 19,
       type: 1,
       status: "P",
       favorites: { artist: "Picasso", food: "pizza" },
       finished: [ 17, 3 ],
       badges: [ "blue", "black" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 85, bonus: 10 }
       ]
     },
     {
       _id: 2,
       name: "bob",
       age: 42,
       type: 1,
       status: "A",
       favorites: { artist: "Miro", food: "meringue" },
       finished: [ 11, 25 ],
       badges: [ "green" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 64, bonus: 12 }
       ]
     },
     {
       _id: 3,
       name: "ahn",
       age: 22,
       type: 2,
       status: "A",
       favorites: { artist: "Cassatt", food: "cake" },
       finished: [ 6 ],
       badges: [ "blue", "red" ],
       points: [
          { points: 81, bonus: 8 },
          { points: 55, bonus: 20 }
       ]
     },
     {
       _id: 4,
       name: "xi",
       age: 34,
       type: 2,
       status: "D",
       favorites: { artist: "Chagall", food: "chocolate" },
       finished: [ 5, 11 ],
       badges: [ "red", "black" ],
       points: [
          { points: 53, bonus: 15 },
          { points: 51, bonus: 15 }
       ]
     },
     {
       _id: 5,
       name: "xyz",
       age: 23,
       type: 2,
       status: "D",
       favorites: { artist: "Noguchi", food: "nougat" },
       finished: [ 14, 6 ],
       badges: [ "orange" ],
       points: [
          { points: 71, bonus: 20 }
       ]
     },
     {
       _id: 6,
       name: "abc",
       age: 43,
       type: 1,
       status: "A",
       favorites: { food: "pizza", artist: "Picasso" },
       finished: [ 18, 12 ],
       badges: [ "black", "blue" ],
       points: [
          { points: 78, bonus: 8 },
          { points: 57, bonus: 7 }
       ]
     }
  ]
)
           

2、練習

1、查詢status為A的文檔
> db.users.find({status:"A"})
{ "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue" }, "finished" : [ 11, 25 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] }
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
>
           
2、查詢status為P或D的文檔
> db.users.find({status:{$in:["P","D"]}})
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
{ "_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate" }, "finished" : [ 5, 11 ], "badges" : [ "red", "black" ], "points" : [ { "points" : 53, "bonus" : 15 }, { "points" : 51, "bonus" : 15 } ] }
{ "_id" : 5, "name" : "xyz", "age" : 23, "type" : 2, "status" : "D", "favorites" : { "artist" : "Noguchi", "food" : "nougat" }, "finished" : [ 14, 6 ], "badges" : [ "orange" ], "points" : [ { "points" : 71, "bonus" : 20 } ] }
           
3、查詢status為A并且age小于30的文檔
> db.users.find({status:"A",age:{$lt:30}})
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
           
4、查詢status為A或者age小于30的文檔
> db.users.find({$or:[{status:"A"},{age:{$lt:30}}]})
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
{ "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue" }, "finished" : [ 11, 25 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] }
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
{ "_id" : 5, "name" : "xyz", "age" : 23, "type" : 2, "status" : "D", "favorites" : { "artist" : "Noguchi", "food" : "nougat" }, "finished" : [ 14, 6 ], "badges" : [ "orange" ], "points" : [ { "points" : 71, "bonus" : 20 } ] }
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
           
5、查詢status為A并且要麼age小于30要麼type為1的文檔
> db.users.find({status:"A",$or:[{age:{$lt:30}},{type:1}]})
{ "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue" }, "finished" : [ 11, 25 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] }
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
           
6、嵌套文檔的精确查詢
> db.users.find( { favorites: { artist: "Picasso", food: "pizza" } } )
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
           
7、嵌套文檔中字段的等于比對
> db.users.find( { "favorites.artist": "Picasso" } )
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
           
8、數組中的精确比對
> db.users.find( { badges: [ "blue", "black" ] } )
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
           
9、比對數組中包含某個元素的文檔
> db.users.find( { badges: "black" } )
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
{ "_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate" }, "finished" : [ 5, 11 ], "badges" : [ "red", "black" ], "points" : [ { "points" : 53, "bonus" : 15 }, { "points" : 51, "bonus" : 15 } ] }
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
           
10、比對數組指定位置為某個值的元素
> db.users.find( { "badges.0": "black" } )
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
           
11、

$elemMatch

查詢數組中至少有一個元素滿足所有指定條件的文檔

至少有一個元素滿足小于20并且大于15。

> db.users.find( { finished: { $elemMatch: { $gt: 15, $lt: 20 } } } )
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
           
11、元素組合滿足查詢條件

查詢一個元素小于15另一個元素大于20或者某一個元素同時滿足這兩個條件

> db.users.find( { finished: { $gt: 15, $lt: 20 } } )
{ "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
{ "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue" }, "finished" : [ 11, 25 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] }
{ "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
           
12、使用數組指定索引比對嵌入文檔中的字段
> db.users.find( { 'points.0.points': { $lte: 55 } } )
{ "_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate" }, "finished" : [ 5, 11 ], "badges" : [ "red", "black" ], "points" : [ { "points" : 53, "bonus" : 15 }, { "points" : 51, "bonus" : 15 } ] }
           
13、使用數組不指定索引比對嵌入文檔中的字段
> db.users.find( { 'points.points': { $lte: 55 } } )
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
{ "_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate" }, "finished" : [ 5, 11 ], "badges" : [ "red", "black" ], "points" : [ { "points" : 53, "bonus" : 15 }, { "points" : 51, "bonus" : 15 } ] }
           
14、單個元素滿足條件

使用

$elemMatch

操作符為數組元素指定符合條件,以查詢數組中至少一個元素滿足所有指定條件的文檔。

下面的例子查詢

points

數組有至少一個包含

points

小于等于

70

并且字段

bonus

等于

20

的内嵌文檔的文檔。

> db.users.find( { points: { $elemMatch: { points: { $lte: 70 }, bonus: 20 } } } )
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
           
15、元素組合滿足某個條件
> db.users.find( { "points.points": { $lte: 70 }, "points.bonus": 20 } )
{ "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue" }, "finished" : [ 11, 25 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] }
{ "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
           

3、傳回查詢的映射字段

插入資料:

db.users.insertMany(
  [
     {
       _id: 1,
       name: "sue",
       age: 19,
       type: 1,
       status: "P",
       favorites: { artist: "Picasso", food: "pizza" },
       finished: [ 17, 3 ],
       badges: [ "blue", "black" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 85, bonus: 10 }
       ]
     },
     {
       _id: 2,
       name: "bob",
       age: 42,
       type: 1,
       status: "A",
       favorites: { artist: "Miro", food: "meringue" },
       finished: [ 11, 25 ],
       badges: [ "green" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 64, bonus: 12 }
       ]
     },
     {
       _id: 3,
       name: "ahn",
       age: 22,
       type: 2,
       status: "A",
       favorites: { artist: "Cassatt", food: "cake" },
       finished: [ 6 ],
       badges: [ "blue", "red" ],
       points: [
          { points: 81, bonus: 8 },
          { points: 55, bonus: 20 }
       ]
     },
     {
       _id: 4,
       name: "xi",
       age: 34,
       type: 2,
       status: "D",
       favorites: { artist: "Chagall", food: "chocolate" },
       finished: [ 5, 11 ],
       badges: [ "red", "black" ],
       points: [
          { points: 53, bonus: 15 },
          { points: 51, bonus: 15 }
       ]
     },
     {
       _id: 5,
       name: "xyz",
       age: 23,
       type: 2,
       status: "D",
       favorites: { artist: "Noguchi", food: "nougat" },
       finished: [ 14, 6 ],
       badges: [ "orange" ],
       points: [
          { points: 71, bonus: 20 }
       ]
     },
     {
       _id: 6,
       name: "abc",
       age: 43,
       type: 1,
       status: "A",
       favorites: { food: "pizza", artist: "Picasso" },
       finished: [ 18, 12 ],
       badges: [ "black", "blue" ],
       points: [
          { points: 78, bonus: 8 },
          { points: 57, bonus: 7 }
       ]
     }
  ]
)
           
1、映射文檔

映射文檔限制傳回比對文檔的所有字段,映射文檔可以指明包括哪些字段或者排除哪些字段,格式為:

{ field1: , field2: }
  • 1或true在傳回的文檔中包含字段
  • 0或者false排除該字段
  • 使用Projection Operators表達式

其中_id字段為預設顯示的,當不想顯示時必須設定為0。并且在指定時要麼都設定為1,要麼都設定為0,不能部分設定為1,部分設定為0.

  1. 傳回比對文檔的所有字段
    如果沒有指定映射,

    db.collection.find()

    方法将會傳回滿足查詢的所有文檔的所有字段。
    > db.users.find({status:"P"})
    { "_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza" }, "finished" : [ 17, 3 ], "badges" : [ "blue", "black" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 85, "bonus" : 10 } ] }
               
  2. 隻傳回指定字段和

    _id

    字段
    > db.users.find({status:"A"},{name:1,status:1})
    { "_id" : 2, "name" : "bob", "status" : "A" }
    { "_id" : 3, "name" : "ahn", "status" : "A" }
    { "_id" : 6, "name" : "abc", "status" : "A" }
               
  3. 隻傳回指定字段
    > db.users.find({status:"A"},{name:1,status:1,_id:0})
    { "name" : "bob", "status" : "A" }
    { "name" : "ahn", "status" : "A" }
    { "name" : "abc", "status" : "A" }
               
  4. 傳回排除字段之外的所有字段
    > db.users.find({status:"A"},{favorites:0,points:0})
    { "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "finished" : [ 11, 25 ], "badges" : [ "green" ] }
    { "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "finished" : [ 6 ], "badges" : [ "blue", "red" ] }
    { "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ] }
               
  5. 傳回嵌入文檔中的指定字段
    使用dot notation傳回嵌入文檔中的特定字段
    • 傳回favorites文檔中的food字段,food字段仍然保持嵌入在favorites文檔中。
      > db.users.find({status:"A"},{name:1,status:1,'favorites.food':1})
      { "_id" : 2, "name" : "bob", "status" : "A", "favorites" : { "food" : "meringue" } }
      { "_id" : 3, "name" : "ahn", "status" : "A", "favorites" : { "food" : "cake" } }
      { "_id" : 6, "name" : "abc", "status" : "A", "favorites" : { "food" : "pizza" } }
                 
  6. 排除嵌入文檔中的特定字段
    排除favorites中的food,其他的仍然嵌套顯示。
    > db.users.find({status:"A"},{'favorites.food':0})
    { "_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro" }, "finished" : [ 11, 25 ], "badges" : [ "green" ], "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] }
    { "_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt" }, "finished" : [ 6 ], "badges" : [ "blue", "red" ], "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
    { "_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "artist" : "Picasso" }, "finished" : [ 18, 12 ], "badges" : [ "black", "blue" ], "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
               
  7. 映射數組中的嵌入文檔
    使用

    dot notation

    映射嵌入數組中文檔的特定字段。dot notation映射代表

    <array>.<index>

    格式的資料。
    > db.users.find({status:"A"},{name:1,status:1,"points.bonus":1})
    { "_id" : 2, "name" : "bob", "status" : "A", "points" : [ { "bonus" : 20 }, { "bonus" : 12 } ] }
    { "_id" : 3, "name" : "ahn", "status" : "A", "points" : [ { "bonus" : 8 }, { "bonus" : 20 } ] }
    { "_id" : 6, "name" : "abc", "status" : "A", "points" : [ { "bonus" : 8 }, { "bonus" : 7 } ] }
               
  8. 映射傳回數組中特定的數組元素(切片)
    對于包含數組的字段,MongoDB提供了以下的映射操作符:

    $elemMatch

    ,

    $slice

    ,以及

    $

    示例:傳回數組中的最後一個元素

    > db.users.find({status:"A"},{name:1,status:1,"points":{$slice:-1}})
    { "_id" : 2, "name" : "bob", "status" : "A", "points" : [ { "points" : 64, "bonus" : 12 } ] }
    { "_id" : 3, "name" : "ahn", "status" : "A", "points" : [ { "points" : 55, "bonus" : 20 } ] }
    { "_id" : 6, "name" : "abc", "status" : "A", "points" : [ { "points" : 57, "bonus" : 7 } ] }
               
    示例:傳回數組中的第1,2個元素
    > db.users.find({status:"A"},{name:1,status:1,"points":{$slice:[0,2]}})
    { "_id" : 2, "name" : "bob", "status" : "A", "points" : [ { "points" : 85, "bonus" : 20 }, { "points" : 64, "bonus" : 12 } ] }
    { "_id" : 3, "name" : "ahn", "status" : "A", "points" : [ { "points" : 81, "bonus" : 8 }, { "points" : 55, "bonus" : 20 } ] }
    { "_id" : 6, "name" : "abc", "status" : "A", "points" : [ { "points" : 78, "bonus" : 8 }, { "points" : 57, "bonus" : 7 } ] }
               

4、查詢值為Null或不存在的字段

首先插入資料:

db.users.insert(
   [
      { "_id" : 900, "name" : null },
      { "_id" : 901 }
   ]
)
           
  1. 相等過濾器
    使用相等查詢,會傳回結果為null的或不存在該字段的資料。
    > db.users.find({name:null})
    { "_id" : 900, "name" : null }
    { "_id" : 901 }
               

    注意:

    如果在查詢中使用了

    sparse

    (稀疏索引),那麼查詢将僅僅比對null值,而不比對不存在的字段。

    稀疏索引:

    稀疏索引指存儲那些有被索引鍵的文檔的索引項,即使被索引鍵的值是null也會被索引(譯者注:請注意,這裡對null的處理和那些特殊索引的預設稀疏特性有細微差别,比如文本索引,2d索引等)。索引會跳過所有不包含被索引鍵的文檔。這個索引之是以稱為 “稀疏” 是因為它并不包括集合中的所有文檔。與之相反,非稀疏的索引會索引每一篇文檔,如果一篇文檔不含被索引鍵則為它存儲一個null值。

  2. 類型篩選
    在BSON類型中null的值為10,是以可以使用以下方式查詢Null:
    > db.users.find({name:{$type:10}})
    { "_id" : 900, "name" : null }
               
  3. 存在性篩選
    存在性篩選可以篩選出那些不存在該字段的資料,1代表存在,0代表不存在。
    > db.users.find({name:{$exists:0}})
    { "_id" : 901 }
               

5、在mongo指令行中疊代遊标

首先插入資料:

  1. 手動疊代遊标
    在mongo指令中,當使用

    var

    關鍵字把

    find()

    傳回的遊标指派給一個變量時,它将不會自動疊代。

    在指令行中,可以調用遊标變量疊代最多20次并且列印比對的文檔。

    > var myCursor = db.goods.find({type:2})
    > myCursor
    { "_id" : 2, "type" : 2 }
               

可以使用遊标的

next()

方法來通路文檔:

> var myCursor = db.goods.find( { type: 2 } )
> while(myCursor.hasNext){print(tojson(myCursor.next()))}
{ "_id" : 2, "type" : 2 }
{ "_id" : 4, "type" : 2 }
{ "_id" : 5, "type" : 2 }
2020-07-09T14:52:14.975+0800 E QUERY    [thread1] Error: error hasNext: false :
DBQuery.prototype.[email protected]/mongo/shell/query.js:305:1
@(shell):1:38
           
  • 也可以使用

    printjson()

    方法替代

    print(tojson())

> var myCursor = db.goods.find( { type: 2 } )
> while(myCursor.hasNext){printjson(myCursor.next())}
{ "_id" : 2, "type" : 2 }
{ "_id" : 4, "type" : 2 }
{ "_id" : 5, "type" : 2 }
2020-07-09T14:54:01.521+0800 E QUERY    [thread1] Error: error hasNext: false :
DBQuery.prototype.[email protected]/mongo/shell/query.js:305:1
@(shell):1:35
           
  • 也可以使用遊标方法

    forEach()

    來疊代遊标并且通路文檔。
> var myCursor = db.goods.find( { type: 2 } )
> myCursor.forEach(printjson)
{ "_id" : 2, "type" : 2 }
{ "_id" : 4, "type" : 2 }
{ "_id" : 5, "type" : 2 }
           
  1. 疊代器索引
    在mongo指令行中,可以使用:method:’~cursor.toArray()'方法來疊代遊标,并且以數組的形式來傳回文檔。
    > var myCursor = db.goods.find({type:2})
    > var documentArray = myCursor.toArray()
    > var myDocument = documentArray[0]
    > myDocument
    { "_id" : 2, "type" : 2 }
    > var myDocument = documentArray[3]
    > myDocument
    >
               
  2. Cursor Behaviors(遊标行為)
    1. 關閉非活動遊标

      預設情況下,伺服器将在限制10分鐘後或用戶端用盡光标後自動關閉光标。要覆寫此行為時,可以使用

      cursor.noCursorTimeout()

      var myCursor = db.users.find().noCursorTimeout();
                 
      當設定了

      noCursorTimeout

      之後,必須要使用

      cursor.close()

      關閉遊标或者耗盡遊标的方式關閉遊标。
    2. 光标隔離

      當光标傳回文檔時,其他操作可能會與查詢交錯。對于MMAPv1存儲引擎來說,對文檔進行幹預的寫操作可能會導緻遊标傳回一個文檔(如果該文檔已更改)多次。

      MMAPv1是MongoDB基于記憶體映射檔案的原始存儲引擎。它在大量插入,讀取和就地更新的工作負載方面表現出色

      從3.2版本開始。MMAPv1不再是預設存儲引擎;WiredTige成為預設的存儲引擎。

    3. 光标批次

      MongoDB伺服器批量傳回查詢結果。批進行中的資料量将不超過BSON文檔的最大大小。可以使用batchSize()和limit()覆寫預設大小。

      3.4新版功能:find(),aggregate(),listIndexes和listCollections類型的操作每批最多傳回16兆位元組。batchSize()可以強制執行一個較小的限制,但是不能執行較大的限制。

      BSON文檔最大大小為16MB,嵌套深度級别不超過100
      當周遊遊标并到達傳回批處理的末尾時,如果有更多結果,

      cursor.next()

      将執行getMore操作以檢索下一個批處理。要檢視疊代遊标時批進行中剩餘多少文檔,可以使用

      objsLeftIntatch()

      方法。
      > var myCursor = db.goods.find()
      > var myFirstDocument =  myCursor.hasNext()?myCursor.next():null
      > myCursor.objsLeftInBatch()
      5
                 
  3. Cursor Information(光标資訊)

    db.serverStatus()

    方法傳回的文檔,其中包括度量字段,該名額字段包含metrics.cursor以下資訊字段:
    • 自上次伺服器重新啟動以來逾時的遊标數
    • 設定了選項

      DBQuery.Option.noTimeout

      的打開遊标的數量, 以防止一段時間不活動後發生逾時
    • “固定”打開遊标的數量
    • 打開的遊标總數
    > db.serverStatus().metrics.cursor
    {
            "timedOut" : NumberLong(0),
            "open" : {
                    "noTimeout" : NumberLong(0),
                    "pinned" : NumberLong(0),
                    "total" : NumberLong(0)
            }
    }
    >
               

三、更新文檔

1、更新介紹

MongoDB中提供了如下的集合更新方式:

方法 描述

db.collection.updateOne()

即使可能有多個文檔通過過濾條件比對到,但是也最多也隻更新一個文檔。3.2新版功能。

db.collection.updateMany()

更新所有通過過濾條件比對到的文檔。3.2新版功能。

db.collection.replaceOne()

即使可能有多個文檔通過過濾條件比對到,但是也最多也隻能替換一個文檔。3.2新版功能。

db.collection.update()

即使可能有多個文檔通過過濾條件比對到,但是也最多也隻更新或替換一個文檔。預設情況下,

db.collection.update()

隻更新一個文檔。要更新多個文檔時,可以使用 multi選項。

文法:db.collection.update(查詢表達式,新值,選項)

注意:使用下面語句時,不是更新資料,而是更新文檔。更新就是用新文檔替換舊文檔。

更新方法需要接收以下參數:

  1. 過濾條件:決定更新哪些文檔。使用查詢表達是過濾内容。
  2. 更新文檔——指定要執行的修改或者替換文檔——完全替換比對文檔(除了_id字段)
  3. 選項

2、行為表現

1、原子性

MongoDB中所有的寫操作在單一文檔層級上是原子的。

2、_id字段

一旦設定,不能更新

_id

字段的值,也不能用有不同

_id

字段值得替換文檔來替換已經存在的文檔。

3、文檔大小

當執行更新操作增加的文檔大小超過了為該文檔配置設定的記憶體空間時,更新操作會在磁盤上重定位該文檔。

4、字段順序

MongoDB按照文檔寫入的順序整理文檔字段,除了以下情況:

  • _id字段始終是文檔的第一個字段
  • 包括字段名稱的renaming操作可能導緻文檔中的字段重新排序。
在2.6版開始,MongoDB主動嘗試保持字段在文檔中的順序。2.6版本之前,MongoDB不會主動保持文檔中的字段的順序。
5、upsert選項

如果

db.collection.update()

db.collection.updateOne()

db.collection.updateMany()

或者

db.collection.replaceOne()

包含

upsert : true

并且 沒有文檔比對指定的過濾器,那麼此操作會建立一個新文檔并插入它。如果有比對的文檔,那麼此操作修改或替換比對的單個或多個文檔。

3、更新操作

首先插入資料:

db.users.insertMany(
   [
     {
       _id: 1,
       name: "sue",
       age: 19,
       type: 1,
       status: "P",
       favorites: { artist: "Picasso", food: "pizza" },
       finished: [ 17, 3 ],
       badges: [ "blue", "black" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 85, bonus: 10 }
       ]
     },
     {
       _id: 2,
       name: "bob",
       age: 42,
       type: 1,
       status: "A",
       favorites: { artist: "Miro", food: "meringue" },
       finished: [ 11, 25 ],
       badges: [ "green" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 64, bonus: 12 }
       ]
     },
     {
       _id: 3,
       name: "ahn",
       age: 22,
       type: 2,
       status: "A",
       favorites: { artist: "Cassatt", food: "cake" },
       finished: [ 6 ],
       badges: [ "blue", "Picasso" ],
       points: [
          { points: 81, bonus: 8 },
          { points: 55, bonus: 20 }
       ]
     },
     {
       _id: 4,
       name: "xi",
       age: 34,
       type: 2,
       status: "D",
       favorites: { artist: "Chagall", food: "chocolate" },
       finished: [ 5, 11 ],
       badges: [ "Picasso", "black" ],
       points: [
          { points: 53, bonus: 15 },
          { points: 51, bonus: 15 }
       ]
     },
     {
       _id: 5,
       name: "xyz",
       age: 23,
       type: 2,
       status: "D",
       favorites: { artist: "Noguchi", food: "nougat" },
       finished: [ 14, 6 ],
       badges: [ "orange" ],
       points: [
          { points: 71, bonus: 20 }
       ]
     },
     {
       _id: 6,
       name: "abc",
       age: 43,
       type: 1,
       status: "A",
       favorites: { food: "pizza", artist: "Picasso" },
       finished: [ 18, 12 ],
       badges: [ "black", "blue" ],
       points: [
          { points: 78, bonus: 8 },
          { points: 57, bonus: 7 }
       ]
     }
   ]
)
           
1、$set——修改指定字段

update隻能更新查詢到的第一個資料。

  • 使用

    $set

    操作符更新

    favorites.food

    字段的值為

    "pie"

    并更新

    type

    字段的值為

    3

    ,
  • 使用

    $currentDate

    操作符更新

    lastModified

    字段的值到目前日期。如果

    lastModified

    字段不存在,

    $currentDate

    會建立該字段。
    > db.users.updateOne({"favorates.artist":"Picasso"},{$set:{"favorites.food":"pie",type:3},$currentDate:{lastModified:true}})
    { "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }
               
2、$unset——删除某個列
db.collection.update({name:'lisi'},{$unset:{age:30}})
           
3、$rename——重命名某個列
db.collection.update({name:'wangwu'},{$rename:{'age':'max-age'}})
           
4、$inc——增加某個列
db.collection.update({name:'hahaha'},{$inc:{age:20}})
           
5、選項:{upsert:true/false,multi:true/false}

upsert:true/false:預設為false,為true時,不存在則插入,如果存在就更新。

multi:true/false預設為false,為true時,會更新比對到的所有資料。

四、删除文檔

1、删除的方法

方法 描述

db.collection.remove()

删除所有符合條件的資料,不寫條件時删除所有

db.collection.deleteOne()

最多删除一個符合條件的文檔。3.2 新版功能.

db.collection.deleteMany()

删除所有比對指定過濾條件的文檔.3.2 新版功能.

注意:

1.查詢表達式依然是個json對象{age:20}

2.查詢表達式比對的行,将被删除。

3.如果不寫查詢表達式,collection中的所有文檔将被删除。

2、删除的行為表現

1、索引

即使把文檔中的所有資料都删除了,索引也不會被删除。

2、原子性

MongoDB所有寫操作在單一文檔層級上是原子的。如果想要删除集合中的所有資料,可以直接删除集合,然後重新集合和索引,這種方式更為高效。

3、删除操作

db.collection.remove(查詢表達式)

{justOne:true/false},是否隻删除一行,預設為false。

  1. 删除stu表中sn屬性值為’001’的文檔
    db.stu.remove({sn:'001'})
               
  2. 删除stu表中gender屬性為m的文檔,隻删除1行
    db.stu.remove({gender:'m',true})
               
  3. 删除第一個

    status

    字段等于

    "A"

    的文檔
    db.users.remove( { status: "D" }, 1)
               

除所有 |

|

db.collection.deleteOne()

| 最多删除一個符合條件的文檔。3.2 新版功能. |

|

db.collection.deleteMany()

| 删除所有比對指定過濾條件的文檔.3.2 新版功能. |

注意:

1.查詢表達式依然是個json對象{age:20}

2.查詢表達式比對的行,将被删除。

3.如果不寫查詢表達式,collection中的所有文檔将被删除。

2、删除的行為表現

1、索引

即使把文檔中的所有資料都删除了,索引也不會被删除。

2、原子性

MongoDB所有寫操作在單一文檔層級上是原子的。如果想要删除集合中的所有資料,可以直接删除集合,然後重新集合和索引,這種方式更為高效。

3、删除操作

db.collection.remove(查詢表達式)

{justOne:true/false},是否隻删除一行,預設為false。

  1. 删除stu表中sn屬性值為’001’的文檔
    db.stu.remove({sn:'001'})
               
  2. 删除stu表中gender屬性為m的文檔,隻删除1行
    db.stu.remove({gender:'m',true})
               
  3. 删除第一個

    status

    字段等于

    "A"

    的文檔
    db.users.remove( { status: "D" }, 1)