Mongoose实现虚拟字段查询的方法详解


Posted in Javascript onAugust 15, 2017

前言

不知道大家知不知道,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 }] });
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
简单JS代码压缩器
Oct 12 Javascript
基于jquery的从一个页面跳转到另一个页面的指定位置的实现代码(带平滑移动的效果)
May 24 Javascript
javascript 常用功能总结
Mar 18 Javascript
Jquery原生态实现表格header头随滚动条滚动而滚动
Mar 18 Javascript
手机开发必备技巧:javascript及CSS功能代码分享
May 25 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
Aug 21 Javascript
JavaScript队列的应用实例详解【经典数据结构】
Apr 12 Javascript
vue 实现剪裁图片并上传服务器功能
Mar 01 Javascript
vue实现选项卡及选项卡切换效果
Apr 24 Javascript
基于js Canvas实现二次贝塞尔曲线
Dec 25 Javascript
vue实现输入框的模糊查询的示例代码(节流函数的应用场景)
Sep 01 Javascript
如何区分vue中的v-show 与 v-if
Sep 08 Javascript
深入浅析Vue不同场景下组件间的数据交流
Aug 15 #Javascript
React应用中使用Bootstrap的方法
Aug 15 #Javascript
JavaScript函数中的this四种绑定形式
Aug 15 #Javascript
详解react使用react-bootstrap当轮子造车
Aug 15 #Javascript
JScript实现表格的简单操作
Aug 15 #Javascript
AngularJS日程表案例详解
Aug 15 #Javascript
jQuery实现菜单栏导航效果
Aug 15 #jQuery
You might like
回首过去10年中最搞笑的10部动漫,哪一部让你节操尽碎?
2020/03/03 日漫
说明的比较细的php 正则学习实例
2008/07/30 PHP
PHP模块 Memcached功能多于Memcache
2011/06/14 PHP
关于PHP中Object对象的笔记分享
2011/06/28 PHP
thinkphp 框架数据库切换实现方法分析
2020/05/18 PHP
javascript引用对象的方法代码
2007/08/13 Javascript
Javascript 实现TreeView CheckBox全选效果
2010/01/11 Javascript
小议Javascript中的this指针
2010/03/18 Javascript
js变换显示图片的实例
2013/04/16 Javascript
js获取php变量的实现代码
2013/08/10 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
2015/03/09 Javascript
JavaScript获取页面中第一个锚定文本的方法
2015/04/03 Javascript
js与jQuery实现checkbox复选框全选/全不选的方法
2016/01/05 Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
2016/01/19 Javascript
javascript+css3 实现动态按钮菜单特效
2016/02/06 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
2016/05/18 Javascript
Bootstrap CSS组件之按钮下拉菜单
2016/12/17 Javascript
jQuery实现的简单悬浮层功能完整实例
2017/01/23 Javascript
Vue2.0实现购物车功能
2017/06/05 Javascript
js中Object.defineProperty()方法的不详解
2018/07/09 Javascript
[01:13:51]TNC vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python网络编程示例(客户端与服务端)
2014/04/24 Python
Python 将RGB图像转换为Pytho灰度图像的实例
2017/11/14 Python
Python实现的简单读写csv文件操作示例
2018/07/12 Python
PyCharm安装Markdown插件的两种方法
2019/06/24 Python
python调用支付宝支付接口流程
2019/08/15 Python
基于Python实现扑克牌面试题
2019/12/11 Python
python3检查字典传入函数键是否齐全的实例
2020/06/05 Python
python 模拟登陆163邮箱
2020/12/15 Python
matplotlib实现数据实时刷新的示例代码
2021/01/05 Python
css3新单位vw、vh的使用教程
2018/03/23 HTML / CSS
OLEDBConnection和SQLConnection有什么区别
2013/05/31 面试题
特种设备安全管理制度
2015/08/06 职场文书
预备党员表决心的话
2015/09/22 职场文书
html实现随机点名器的示例代码
2021/04/02 Javascript
python 下划线的多种应用场景总结
2021/05/12 Python