Something about ThinkJs and Mongoose
使用mongoose進行查詢時的一些稍微複雜的查詢方法,由於是初學,也記錄一下:
關聯查詢
mongoose可以通過populate方法直接進行關聯查詢,例如我們有這樣的兩個例項:
const articleSchema = new Schema({ title: String, category: { type: Schema.Types.ObjectId, ref: 'Catetory' } }) const cateSchema = new Schema({ name: String })
可以直接這樣進行關聯查詢:
articleModel.find({}) .populate({ path: 'category', match, select, options ... })
聚合查詢
可以使用aggregate進行聚合查詢
主要聚合的OPERATION可以在ofollow,noindex">這裡 進行檢視
比如,針對文章列表,我們想要對其進行時間歸檔,可以按以下方式查詢:
aggregate([{ $project: { time: { $dateToString: { format: "%Y-%m", date: "$create_at" } }, data: { _id: '$_id', title: '$title' } } }, { $group: { _id: '$time', list: {$push: '$data'} } }, { $sort: { _id: -1 } }])
大體思路就是,使用$project修改文件結構,新增time和data欄位,time表示對應的年和月,如2018-07。
然後按照對應的time進行分組,將同組的data插入到一個數組中。
最後按照_id進行排序。最後我們可以輸出以下結構的資料了:
_id: '2018-08', list: [{ _id: 'sdfsdfsdf', title: '第一篇文章' }, { _id: 'sdfaaaaa', title: '第二篇' }] }, { _id: '2018-08', list: [{ _id: 'sdfsdfsdf', title: '第3篇文章' }, { _id: 'sdfaaaaa', title: '第4篇' }] }]
問題
think-mongoose對populate的支援問題
在使用think-mongoose進行populate時,會出現相關的model未進行註冊
需要在return schema時手動例項對應的model
{ get schema () { const schema = new Schema({ type: { type: Schema.Types.ObjectId, ref: `${this.tablePrefix}types` } }) think.mongoose('types') return schema } }
其中,types是根據model裡的檔名稱來進行對應的
使用Context.model返回物件無法確定其型別
我們在Controller中,通過this.mongoose()方法獲取Model例項,但是返回的物件是通用的MongooseModel,
typescript無法識別真實例項上的方法,我們需要強制對其進行轉化。
private getArticleModel(): ArticleModel { return this.mongoose('article') as ArticleModel }
think.Mongoose例項上不能對mongoose的model進行友好提示
看了下think-mongoose的宣告檔案,針對think.Mongoose的宣告如下:
interface MongooseModel { new(modelName?: string, config?: object): MongooseModel; readonly tablePrefix: string; readonly tableName: string; models: object; mongoose(name: string): MongooseModel; }
可以看到其未整合mongoose的model宣告,我們可以讓其整合Model宣告,這樣在think.Mongoose例項上呼叫this.find等方法時,就會進行友好的提示及驗證了
interface Base extends Document {} interface MongooseModel extends Model<Base> {...}