這篇文章主要給大家介紹了關於Mongoose實現虛擬字段查詢的相關資料,文中透過範例程式碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。
前言
不知道大家知不知道,mongoose為資料模型提供了虛擬屬性, 藉此可以更一致、方便地讀寫模型屬性,類似C#或Java中的存取器。 我們知道虛擬屬性在Query階段一定是查不到的,因為事實上MongoDB並沒有儲存這些屬性。 但是否可以透過一個攔截器來實現虛擬屬性的查詢呢?
這個問題很有趣,而且在很多場景下都相當方便。例如:
實作一個暴力的全文檢索時,需要對多個欄位匹配統一查詢詞,該查詢詞可抽象化為虛擬屬性;
#多處都需要進行同一個複雜條件的查詢時,可以用虛擬屬性封裝該查詢條件。
事實上,虛擬屬性查詢和虛擬屬性讀寫都是為了程式碼重複使用。
Mongoose 中的 Hook
#Mongoose Schema幾乎所有靜態方法和物件方法都添加了 .pre和.post鉤子。 這些鉤子其實就是函數鉤子,採用hooks-js的實作。
來自官網的範例:
var hooks = require('hooks') , Document = require('./path/to/some/document/constructor'); // Add hooks' methods: `hook`, `pre`, and `post` for (var k in hooks) { Document[k] = hooks[k]; } // Define a new method that is able to invoke pre and post middleware Document.hook('save', Document.prototype.save); // 上述代码在mongoose中实现 ///////////////////////////////////////////////////////////////////// // 下面的代码则是mongoose提供的Hook API // Define a middleware function to be invoked before 'save' Document.pre('save', function validate(next) { // ... });
在Document.save()
被呼叫時,上述validate函數就會被回呼。
新增查詢鉤子
Mongoose沒有進一步對hooks-js封裝,這表示我們不能對所有Query方法設定鉤子, 只能一一枚舉需要監視的方法。當然,這不影響我們進行程式碼重複使用。
// 设置 findOne 和 find 钩子 CompanySchema.pre('findOne', preFind).pre('find', preFind);
接下來便著手實作preFind函數。
實作虛擬查詢
在鉤子(preFind)中,我們可以更改查詢條件藉此實作虛擬查詢。 值得注意的是,完全可控的Query意味著我們可以實現任何形式的虛擬查詢。
例如全文檢索:
function preFind() { var word = this.getQuery().word; if(word === undefined) return; // 从真实的Query中删掉虚拟属性 delete this._conditions.word; // 构造正则表达式 var regex = new RegExp(word); // 全文检索 this.where({ $or: [{ title: regex }, { content: regex }, { author: regex }] }); }
以上是詳解Mongoose的虛擬字段查詢實作方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!