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 相关文章推荐
Add Formatted Text to a Word Document
Jun 15 Javascript
JavaScript避免代码的重复执行经验技巧分享
Apr 17 Javascript
jQuery异步加载数据并添加事件示例
Aug 24 Javascript
node.js中的console.info方法使用说明
Dec 09 Javascript
JQuery报错Uncaught TypeError: Illegal invocation的处理方法
Mar 13 Javascript
详解JavaScript中getFullYear()方法的使用
Jun 10 Javascript
JavaScript学习总结之JS、AJAX应用
Jan 29 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
Feb 15 Javascript
JS实现的驼峰式和连字符式转换功能分析
Dec 21 Javascript
微信小程序实现动态改变view标签宽度和高度的方法【附demo源码下载】
Dec 05 Javascript
Vue中的异步组件函数实现代码
Jul 20 Javascript
微信小程序如何实现点击图片放大功能
Jan 21 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
「OVERLORD」动画重要删减!雅儿贝德的背叛?至尊猎杀队结成
2020/04/09 日漫
PHP5 操作MySQL数据库基础代码
2009/09/29 PHP
php中的静态变量的基本用法
2014/03/20 PHP
php处理json格式数据经典案例总结
2016/05/19 PHP
php 使用fopen函数创建、打开文件详解及实例代码
2016/09/24 PHP
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
使用jQuery内容过滤选择器选择元素实例讲解
2013/04/18 Javascript
JS实现点击按钮控制Div变宽、增高及调整背景色的方法
2015/08/05 Javascript
js+css实现文字散开重组动画特效代码分享
2015/08/21 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
AngularJS之ionic 框架下实现 Localstorage本地存储
2017/04/22 Javascript
Angular.Js中过滤器filter与自定义过滤器filter实例详解
2017/05/08 Javascript
Angular2 组件间通过@Input @Output通讯示例
2017/08/24 Javascript
原生JS实现图片无缝滚动方法(附带封装的运动框架)
2017/10/01 Javascript
angularjs使用gulp-uglify压缩后执行报错的解决方法
2018/03/07 Javascript
javascript之分片上传,断点续传的实际项目实现详解
2019/09/05 Javascript
如何基于JS截获动态代码
2019/12/25 Javascript
浅谈vue在html中出现{{}}的原因及解决方式
2020/11/16 Javascript
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
python进阶教程之函数参数的多种传递方法
2014/08/30 Python
Python聚类算法之基本K均值实例详解
2015/11/20 Python
Python中多线程的创建及基本调用方法
2016/07/08 Python
pygame游戏之旅 载入小车图片、更新窗口
2018/11/20 Python
PyCharm安装Markdown插件的两种方法
2019/06/24 Python
python 模拟银行转账功能过程详解
2019/08/06 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
2020/04/08 Python
python操作微信自动发消息的实现(微信聊天机器人)
2020/07/14 Python
基于html5绘制圆形多角图案
2016/04/21 HTML / CSS
Luxplus荷兰:以会员价购买美容产品等,独家优惠
2019/08/30 全球购物
应届大学生简历中的自我评价
2014/01/15 职场文书
清扬洗发水广告词
2014/03/14 职场文书
材料物理专业求职信
2014/09/01 职场文书
春秋淹城导游词
2015/02/11 职场文书
观后感开头
2015/06/19 职场文书
法制教育主题班会
2015/08/13 职场文书
新西兰:最新留学学习计划书写作指南
2019/07/15 职场文书