FindOptions
相關參數
- limit:筆數
- sort:排序
- projection:返回指定欄位
- skip:跳過 N 個欄位
基本使用
findOne
- 單筆查詢
package 源碼
findOne<T = TSchema>(filter: Filter<TSchema>, options?: FindOptions): Promise<T | null>;
interface User {
name: string
age: number
address: string
}
const collection: Collection<User> = db.collection<User>("user");
const query: Filter<User> = {
name: 'Fred'
}
await collection.findOne(query);
find
- 多筆查詢
package 源碼
find(filter: Filter<TSchema>, options?: FindOptions): FindCursor<WithId<TSchema>>;
interface User {
name: string
age: number
address: string
}
const query: Filter<User> = {
name: /F/
}
const cursor = collection.find(query);
let users = await cursor.toArray() // 這才是回傳陣列欄位
返回指定欄位
interface User {
name: string
age: number
address: string
}
const query: Filter<User> = {
name: /F/
}
const option: FindOptions = {
sort: { name: -1 }, // 排序
projection: { name: true, address: true }, // 僅回傳需要的欄位,這就不會回傳 age
}
type ResultUser = Pick<Store, "name" | "address">;
const user = await collection.findOne<ResultUser>(query, option);
分頁搜尋
const req = {
rows: 10, // 筆數
page: 1, // 頁面
}
const query: Filter<User> = {
name: /F/
}
const option: FindOptions = {
sort: { name: -1 }, // 指定某欄位排序
skip: req.rows * (req.page - 1),
limit: req.rows
}
type ResultUser = Pick<Store, "name" | "address">;
const cursor = collection.find(query, option);
let users = await cursor.toArray() // 這才是回傳陣列欄位
運算符
於Find中使用是針對 Filter<TSchema>
進行運算
比較查詢 (Comparison Query)
運算符 | 翻譯 | 格式 |
---|---|---|
$eq | == | {field: {$eq: value} } |
$gt | > | {field: {$gt: value} } |
$gte | >= | {field: {$gte: value} } |
$in | = 範圍 ex == 1~15 1>= && <=15 | { field: { $in: [value1, value2, … valueN ] } } |
$lt | < | {field: {$lt: value} } |
$lte | <= | {field: { $lte: value} } |
$ne | != | {field: {$ne: value} } |
$nin | != 範圍 ex != 1~15 1< && >15 | {field: {$nin: value} } |
// Example
interface User {
name: string
age: number
address: string
}
const query: Filter<User> = {
name: {
$eq : 'Fred'
}
}
邏輯查詢 (Logical Query)
運算符 | 翻譯 | 格式 |
---|---|---|
$and | && | { $and:[{expression1}, {expression2}, … ,{expressionN} ] } |
$or | || | { $or: [{expression1}, {expression2}, … {expressionN} ] } |
// Example
interface User {
name: string
age: number
address: string
}
const query: Filter<User> = {
$or : [
{
name: 'Fred'
},
{
name: 'Leo'
},
]
}
元素查詢 (Element Query)
略,目前感覺用不到
評估查詢 (Evaluation Query) - 進階
運算符 | 翻譯 | 格式 |
---|---|---|
$regex | 正則表示式匹配 | { field: /pattern/options } |
$mod | 餘數運算 | { field: { $mod: [ divisor, remainder ] } } |
$text | 文字索引的欄位內容執行文字搜尋 | {$text:{ $search:string, $language: string, $caseSensitive: boolean, $diacriticSensitive: boolean }} |
$where | 匹配javascript表示式 | { $where: function() { return …; } } |
$expr | 使用聚合表示式 | { $expr: { expression } } |
$jsonSchema | 匹配json綱要 | { $jsonSchema: schema } |
$regex
// Example interface User { name: string age: number address: string } const query: Filter<User> = { { name: { $regex: /F/ } }, }
$mod
db.inventory.insertMany( [ { "_id" : 1, "item" : "abc123", "qty" : 0 }, { "_id" : 2, "item" : "xyz123", "qty" : 5 }, { "_id" : 3, "item" : "ijk123", "qty" : 12 } ] ) db.inventory.find( { qty: { $mod: [ 4, 0 ] } } ) // { "_id" : 1, "item" : "abc123", "qty" : 0 } // { "_id" : 3, "item" : "ijk123", "qty" : 12 }
$text
運算符 型別 翻譯 $search string 查詢,這功能很好用 $language string (ISO 639-1 ) 但很抱歉沒中文 $caseSensitive boolean 大小寫敏感,base on 語系 $diacriticSensitive boolean 相似音,base on 語系 db.articles.insertMany( [ { _id: 1, subject: "coffee", author: "xyz", views: 50 }, { _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, { _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, { _id: 4, subject: "baking", author: "xyz", views: 100 }, { _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, { _id: 6, subject: "Сырники", author: "jkl", views: 80 }, { _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, { _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } ] ) db.articles.find( { $text: { $search: "coffee" } } ) // { _id: 1, subject: 'coffee', author: 'xyz', views: 50 }, // { _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 }, // { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 }
$where
需將MongoDB啟用JavaScript Enablement
功能(預設即啟用),這邊先將這功能略過,若要使用 Aggregation(聚合)功能需要進行 javascript查詢 建議使用$function
代替$where
db.players.insertMany([ { _id: 12378, name: "Steve", username: "steveisawesome", first_login: "2017-01-01" }, { _id: 2, name: "Anya", username: "anya", first_login: "2001-02-02" } ]) db.players.find( { $where: function() { return (hex_md5(this.name) == "9b53e667f30cd329dca1ec9e6a83e994") } } ); // { // "_id" : 2, // "name" : "Anya", // "username" : "anya", // "first_login" : "2001-02-02" // }
$expr
從官網看這篇的時候,會突然資訊量爆棚一堆英文單字,expression / aggregation / stage / pipeline …
其實可專注在,如何分辨使用$expr
/aggregate
? 這件事// 這是使用 aggregate 起手式 db.collection.aggregate() // 這是使用 $expr 起手式 db.collection<User>("user").find({ $expr: ... })
stage / pipeline 曾經做過 CI/CD 或 webpack 優化 的過程中可以看到這英文單字,中文來說就是「階段」
expression 就是在描述「條件」$expr
的條件中可以用聚合表達式查詢功能,下方為官網範例。db.supplies.insertMany([ { "_id" : 1, "item" : "binder", "qty" : NumberInt("100"), "price" : NumberDecimal("12") }, { "_id" : 2, "item" : "notebook", "qty" : NumberInt("200"), "price" : NumberDecimal("8") }, { "_id" : 3, "item" : "pencil", "qty" : NumberInt("50"), "price" : NumberDecimal("6") }, { "_id" : 4, "item" : "eraser", "qty" : NumberInt("150"), "price" : NumberDecimal("3") }, { "_id" : 5, "item" : "legal pad", "qty" : NumberInt("42"), "price" : NumberDecimal("10") } ]) // 使用聚合表達式查詢 let discountedPrice = { $cond: { if: { $gte: ["$qty", 100] }, then: { $multiply: ["$price", NumberDecimal("0.50")] }, else: { $multiply: ["$price", NumberDecimal("0.75")] } } }; db.supplies.find( { $expr: { $lt:[ discountedPrice, NumberDecimal("5") ] } });
$jsonSchema
略,目前感覺用不到
數組查詢 (Array Query)
運算符 | 翻譯 | 格式 |
---|---|---|
$all | 符合這些條件的資料 | { : { $all: [ , … ] } } |
$size | 陣列內數量相符 [1,2] => $size: 2 | { field: { $size: size } } |
總結
查詢為DB超級常見的功能,初期簡易使用即可,可專研 Evaluation Query,若是要更彈性使用,可後續網 aggregation
篇章深入,官網資訊量很多