基本使用
updateOne
- 部分內容單筆修改
const collection: Collection<User> = db.collection<User>("user");
const query = {
name: 'Fred'
}
const update = {
$set: {
name: "Jason"
}
}
await collection.updateOne(query, update);
replaceOne
- 全部內容單筆替換
const collection: Collection<User> = db.collection<User>("user");
const query = {
name: 'Fred'
}
const update = {
name: "Jason",
age: 18,
gender: "male"
}
await collection.replaceOne(query, update);
upsert
- 找不到就新增
const collection: Collection<User> = db.collection<User>("user");
const query = {
name: 'Fred'
}
const update = {
$set: {
name: "Jason"
}
}
const option = {
upsert: true // 找不到就新增
}
await collection.updateOne(query, update, option);
updateMany
- 部分內容多筆修改
採用 sample_mflix.movies
這 collection
,注入資料方法
import { MongoClient } from "mongodb";
// 將 uri 字符串替換為 MongoDB 部署的連接字符串。
const uri = "<connection string uri>";
const client = new MongoClient(uri);
enum Rating {
G = "G",
PG = "PG",
PG_13 = "PG-13",
R = "R",
NR = "NOT RATED",
}
interface Movie {
rated: Rating;
random_review?: string;
}
async function run() {
try {
const database = client.db("sample_mflix");
const movies = database.collection<Movie>("movies");
const result = await movies.updateMany(
{ rated: Rating.G },
{
$set: {
random_review: `看完後我${100 * Math.random()}% 滿意。`,
},
}
);
console.log(`Updated ${result.modifiedCount} documents`);
} finally {
await client.close();
}
}
run().catch(console.dir);
單筆運算符
運算符 | 翻譯 | 格式 |
---|---|---|
$currentDate | 值設定為當前日期,無論是日期還是時間戳 | { $currentDate: { field1: typeSpecification1, … } } |
$inc | Update + value | { $inc: { field1: amount1, field2: amount2, … } } |
$min | Update < value | { $min: { field1: value1, … } } |
$max | Update > value | { $max: { field1: value1, … } } |
$mul | Update * value | { $mul: { field1: number1, … } } |
$rename | 欄位換名稱 | {$rename: { field1: newName1,field2: newName2,…}} |
$set | 重設定 value | {$set: { field1: value1, … } } |
$setOnInsert | 重新設定 doc 原先設定的欄位 | update(query,{$setOnInsert: { field1: value1, … } },{ upsert: true }) |
$unset | 刪除指定欄位 | {$unset: {field1: “”, … } } |
$currentDate
略,認為用不到
$inc
// {
// _id: 1,
// sku: "abc123",
// quantity: 10,
// metrics: { orders: 2, ratings: 3.5 }
// }
db.products.updateOne(
{ sku: "abc123" },
{ $inc: { quantity: -2, "metrics.orders": 1 } }
)
// retrun :
// {
// _id: 1,
// sku: 'abc123',
// quantity: 8, // 10 + -2 = 8
// metrics: { orders: 3, ratings: 3.5 } // 2 + 1 = 3
// }
$min
/** 數字 **/
// { _id: 1, highScore: 800, lowScore: 200 }
db.scores.updateOne( { _id: 1 }, { $min: { lowScore: 150 } } )
// return
// { _id: 1, highScore: 800, lowScore: 150 } // 150 < 200 ,所以被替換了
/** 日期 **/
// { _id: 1, desc: "crafts", dateEntered: ISODate("2013-10-01T05:00:00Z") }
db.tags.updateOne( { _id: 1 }, { $min: { dateEntered: new Date("2013-09-25") } } )
// return
// { _id: 1, desc: "crafts", dateEntered: ISODate("2013-09-25T00:00:00Z") } // 2013-09-25 < 2013-10-01 ,所以被替換了
$max
// { _id: 1, highScore: 800, lowScore: 150 }
db.scores.updateOne( { _id: 1 }, { $max: { lowScore: 200 } } )
// return
// { _id: 1, highScore: 800, lowScore: 200 } // 200 > 150 ,所以被替換了
/** 日期 **/
// { _id: 1, desc: "crafts", dateEntered: ISODate("2013-09-25T05:00:00Z") }
db.tags.updateOne( { _id: 1 }, { $max: { dateEntered: new Date("2013-10-01") } } )
// return
// { _id: 1, desc: "crafts", dateEntered: ISODate("2013-10-01T00:00:00Z") } // 2013-10-01 > 2013-09-25,所以被替換了
$mul
// { "_id" : 1, "item" : "Hats", "price" : Decimal128("10.99"), "quantity" : 25 }
db.products.updateOne(
{ _id: 1 },
{ $mul:
{ price: Decimal128( "1.25" ), quantity: 2}
}
)
// retrun
// { _id: 1, item: 'Hats', price: Decimal128("13.7375"), quantity: 50 } // 10.99 * 1.25 25 * 2
$rename
// {
// "_id": 1,
// "alias": [ "The American Cincinnatus", "The American Fabius" ],
// "mobile": "555-555-5555",
// "nmae": { "first" : "george", "last" : "washington" }
// },
// {
// "_id": 2,
// "alias": [ "My dearest friend" ],
// "mobile": "222-222-2222",
// "nmae": { "first" : "abigail", "last" : "adams" }
// },
// {
// "_id": 3,
// "alias": [ "Amazing grace" ],
// "mobile": "111-111-1111",
// "nmae": { "first" : "grace", "last" : "hopper" }
// }
db.students.updateMany( {}, { $rename: { "nmae": "name" } } )
// return
// {
// "_id": 1,
// "alias": [ "The American Cincinnatus", "The American Fabius" ],
// "mobile": "555-555-5555",
// "name": { "first" : "george", "last" : "washington" }
// }
// {
// "_id" : 2,
// "alias" : [ "My dearest friend" ],
// "mobile" : "222-222-2222",
// "name" : { "first" : "abigail", "last" : "adams" }
// }
// { "_id" : 3,
// "alias" : [ "Amazing grace" ],
// "mobile" : "111-111-1111",
// "name" : { "first" : "grace", "last" : "hopper" } }
$set
// {
// _id: 100,
// quantity: 250,
// instock: true,
// reorder: false,
// details: { model: "14QQ", make: "Clothes Corp" },
// tags: [ "apparel", "clothing" ],
// ratings: [ { by: "Customer007", rating: 4 } ]
// }
db.products.updateOne(
{ _id: 100 },
{ $set:
{
quantity: 500,
details: { model: "2600", make: "Fashionaires" },
tags: [ "coats", "outerwear", "clothing" ]
}
}
)
// return
// {
// _id: 100,
// quantity: 500,
// instock: true,
// reorder: false,
// details: { model: '2600', make: 'Fashionaires' },
// tags: [ 'coats', 'outerwear', 'clothing' ],
// ratings: [ { by: 'Customer007', rating: 4 } ]
// }
$setOnInsert
略,認為用不到
$unset
// { "item": "chisel", "sku": "C001", "quantity": 4, "instock": true },
// { "item": "hammer", "sku": "unknown", "quantity": 3, "instock": true },
db.products.updateOne(
{ sku: "unknown" },
{ $unset: { quantity: "", instock: "" } }
)
// retrun
// { "item": "chisel", "sku": "C001", "quantity": 4, "instock": true },
// { "item": "hammer", "sku": "unknown" },
陣列運算符
運算符 | 翻譯 | 格式 |
---|---|---|
$ | 位置運算符 | { “.$” : value } |
$[] | 全部位置運算符 | { update operator: { “array.$[]” : value } } |
$[<identifier>] | 位置運算符 | { update operator: { “array.$[identifier]” : value } },{ arrayFilters: [ { identifier: condition> } } ] } |
$addToSet | 新增,重複不新增 | {$addToSet: { field1: value1, … } } |
$pop | 移除 第一個 or 最後一個 | |
$pull | 移除 | |
$push | 新增,重複亦新增 | |
$pullAll | 移除多個 |
interface Goods {
name: string;
tags?: string[];
}
interface Store {
name: string;
items: Goods[];
}
const collection: Collection<User> = db.collection<Store>("store");
// 先注入些資料
await collection.insertMany([
{
name: "肯德基",
items: [
{
name: "炸雞",
type: "炸物",
tags: ["熱銷","好吃"],
},
{
name: "薯條",
type: "炸物",
},
],
},
{
name: "麥當勞",
items: [
{
name: "炸雞",
type: "炸物",
tags: ["熱銷"],
},
],
},
]);
$
const query = { "items.type": "炸物" };
const update = {
$push: { "items.$.tags": "當月熱銷" }
};
await collection.updateMany(query, update);
$[]
const query = { "items.type": "炸物" };
const update = {
$push: { "items.$[].tags": "當月熱銷" }
};
await collection.updateMany(query, update);
$[<identifier>]
const query = { name: "肯德基" };
const update = {
$push: { "items.$[i].tags": "當月熱銷" }
};
const options = {
arrayFilters: [
{
"i.name": "薯條",
},
],
};
await collection.updateMany(query, update, options);
$addToSet
// { _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] }
db.inventory.updateOne(
{ _id: 1 },
{ $addToSet: { tags: "accessories" } }
)
// { _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera", "accessories" ] } //沒有就新增
db.inventory.updateOne(
{ _id: 1 },
{ $addToSet: { tags: "camera" } }
)
// { _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera", "accessories" ] } //不動,因為已有
/** 用 $each **/
// { _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }
db.inventory.updateOne(
{ _id: 2 },
{ $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
)
// {
// _id: 2,
// item: "cable",
// tags: [ "electronics", "supplies", "camera", "accessories" ] // "camera", "electronics" 已有,只添加 "accessories"
// }
$pop
// db.students.insertOne( { _id: 1, scores: [ 8, 9, 10 ] } )
db.students.updateOne( { _id: 1 }, { $pop: { scores: -1 } } )
// { _id: 1, scores: [ 9, 10 ] } // -1 扣前面
db.students.updateOne( { _id: 1 }, { $pop: { scores: 1 } } )
// { _id: 1, scores: [ 9 ] } // 1 扣後面
$pull
// {
// _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" ]
// }
db.stores.updateMany(
{ },
{ $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } }
)
// {
// _id: 1,
// fruits: [ 'pears', 'grapes', 'bananas' ], // 移除 "apples", "oranges"
// vegetables: [ 'celery', 'squash' ] // 移除 "carrots"
// },
// {
// _id: 2,
// fruits: [ 'plums', 'kiwis', 'bananas' ], // 移除 "apples", "oranges"
// vegetables: [ 'broccoli', 'zucchini', 'onions' ]
// }
$push
// { _id: 1, scores: [ 44, 78, 38, 80 ] }
db.students.updateOne({ _id: 1 }, { $push: { scores: 89 } })
// { _id: 1, scores: [ 44, 78, 38, 80, 89 ] } // 新增 89
$pullAll
// { _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] }
db.survey.updateOne( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } )
// { "_id" : 1, "scores" : [ 2, 1 ] } // 將 0,5 皆從陣列中移除了
陣列修飾符
修飾符 | 可用之運算符 | 格式 |
---|---|---|
$each | $push / $addToSet | 每一個 |
$position | $push | |
$slice | $push | 切片,正數n:保留前n個/負數n:保留後n個 |
$sort | $push | 排序,1:小到大/-1:大到小 |
$each
// { _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }
db.inventory.updateOne(
{ _id: 2 },
{ $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
)
// {
// _id: 2,
// item: "cable",
// tags: [ "electronics", "supplies", "camera", "accessories" ] // 原先已有 "electronics",僅 添加 "camera", "accessories"
// }
$position
// { "_id" : 2, "scores" : [ 50, 60, 70, 100 ] }
db.students.updateOne(
{ _id: 2 },
{
$push: {
scores: {
$each: [ 20, 30 ],
$position: 2 // 陣列起點位置 開始為 0
}
}
}
)
// { "_id" : 2, "scores" : [ 50, 60, 20, 30, 70, 100 ] }
$slice
// { "_id" : 1, "scores" : [ 40, 50, 60 ] }
db.students.updateOne(
{ _id: 1 },
{
$push: {
scores: {
$each: [ 80, 78, 86 ], // [ 40, 50, 60, 80, 78, 86 ]
$slice: -5 // 後 5 個 [ 50, 60, 80, 78, 86 ]
}
}
}
)
// { "_id" : 1, "scores" : [ 50, 60, 80, 78, 86 ] }
// { "_id" : 2, "scores" : [ 89, 90 ] }
db.students.updateOne(
{ _id: 2 },
{
$push: {
scores: {
$each: [ 100, 20 ], // [ 89, 90, 100, 20 ]
$slice: 3 // 前 3 個 [ 89, 90, 100 ]
}
}
}
)
// { "_id" : 2, "scores" : [ 89, 90, 100 ] }
// {
// "_id" : 3,
// "quizzes" : [
// { "wk": 1, "score" : 10 },
// { "wk": 2, "score" : 8 },
// { "wk": 3, "score" : 5 },
// { "wk": 4, "score" : 6 }
// ]
// }
db.students.updateOne(
{ _id: 3 },
{
$push: {
quizzes: {
$each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ], // [{"wk":1,"score":10},{"wk":2,"score":8},{"wk":3,"score":5},{"wk":4,"score":6},{"wk":5,"score":8},{"wk":6,"score":7},{"wk":7,"score":6}]
$sort: { score: -1 }, // score 大到小排列 [{"wk":1,"score":10},{"wk":2,"score":8},{"wk":5,"score":8},{"wk":6,"score":7},{"wk":4,"score":6},{"wk":7,"score":6},{"wk":3,"score":5}]
$slice: 3 // 取前 3 個 [{"wk":1,"score":10},{"wk":2,"score":8},{"wk":5,"score":8}]
}
}
}
)
// {
// "_id" : 3,
// "quizzes" : [
// { "wk" : 1, "score" : 10 },
// { "wk" : 2, "score" : 8 },
// { "wk" : 5, "score" : 8 }
// ]
// }
$sort
// {
// "_id": 1,
// "quizzes": [
// { "id" : 1, "score" : 6 },
// { "id" : 2, "score" : 9 }
// ]
// }
db.students.updateOne(
{ _id: 1 },
{
$push: {
quizzes: {
$each: [ { id: 3, score: 8 }, { id: 4, score: 7 }, { id: 5, score: 6 } ], // [{"id":1,"score":6},{"id":2,"score":9},{"id":3,"score":8},{"id":4,"score":7},{"id":5,"score":6}]
$sort: { score: 1 } // 小到大 [{"id":1,"score":6},{"id":5,"score":6},{"id":4,"score":7},{"id":3,"score":8},{"id":2,"score":9}]
}
}
}
)
// {
// "_id" : 1,
// "quizzes" : [
// { "id" : 1, "score" : 6 },
// { "id" : 5, "score" : 6 },
// { "id" : 4, "score" : 7 },
// { "id" : 3, "score" : 8 },
// { "id" : 2, "score" : 9 }
// ]
// }
結論
撰寫前,有用一些圖文去細細的寫了一點,但資訊量真的太大了,朝翻譯官方文件著手,範例其實和官方文件範例相同,主要將註解翻譯成中文讓自己看得懂,官方文件其實講解得蠻清楚的,當然是為了往後讓自己翻找好用為主,用表格用程式碼註記回顧依然是我的習慣。