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 相关文章推荐
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
Jan 23 Javascript
Javascript基础教程之关键字和保留字汇总
Jan 18 Javascript
javascript+html5实现仿flash滚动播放图片的方法
Apr 27 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
Jun 05 Javascript
基于JQuery和CSS3实现仿Apple TV海报背景视觉差特效源码分享
Sep 21 Javascript
jQuery多文件异步上传带进度条实例代码
Aug 16 Javascript
Vue2.0父组件与子组件之间的事件发射与接收实例代码
Sep 19 Javascript
AngularJS 表单验证手机号的实例(非必填)
Nov 12 Javascript
Phaser.js实现简单的跑酷游戏附源码下载
Oct 26 Javascript
jQuery判断自定义属性data-val用法示例
Jan 07 jQuery
JavaScript中判断为整数的多种方式及保留两位小数的方法
Sep 09 Javascript
vue使用video插件vue-video-player的示例
Oct 03 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
Windows7下PHP开发环境安装配置图文方法
2010/05/20 PHP
Session服务器配置指南与使用经验的深入解析
2013/06/17 PHP
php页面防重复提交方法总结
2013/11/25 PHP
PHP aes (ecb)解密后乱码问题
2015/06/22 PHP
浅谈php的TS和NTS的区别
2019/03/13 PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
2019/06/17 PHP
让焦点自动跳转
2006/07/01 Javascript
Jquery Ajax学习实例7 Ajax所有过程事件分析示例
2010/03/23 Javascript
jQuery中的bind绑定事件与文本框改变事件的临时解决方法
2010/08/13 Javascript
深入理解jQuery中live与bind方法的区别
2013/12/18 Javascript
常用jQuery选择器总结
2014/07/11 Javascript
javascript二维数组转置实例
2015/01/22 Javascript
在for循环中length值是否需要缓存
2015/07/27 Javascript
基于JavaScript实现下拉列表左右移动代码
2017/02/07 Javascript
JS优化与惰性载入函数实例分析
2017/04/06 Javascript
Angularjs单选框相关的示例代码
2017/08/17 Javascript
JS实现生成由字母与数字组合的随机字符串功能详解
2018/05/25 Javascript
javascript中UMD规范的代码推演
2018/08/29 Javascript
vue将毫秒数转化为正常日期格式的实例
2018/09/16 Javascript
JavaScript实现简单日历效果
2020/09/11 Javascript
Python3.5编程实现修改IIS WEB.CONFIG的方法示例
2017/08/18 Python
解决python大批量读写.doc文件的问题
2018/05/08 Python
python实现俄罗斯方块游戏
2020/03/25 Python
Python简单过滤字母和数字的方法小结
2019/01/09 Python
python3 线性回归验证方法
2019/07/09 Python
css3 矩阵的使用详解
2018/03/20 HTML / CSS
韩国现代百货官网:Hmall
2018/03/21 全球购物
《小动物过冬》教学反思
2014/04/17 职场文书
快餐公司创业计划书
2014/04/29 职场文书
学校党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
事业单位聘任报告
2015/03/02 职场文书
《吃水不忘挖井人》教学反思
2016/02/22 职场文书
python 实现定时任务的四种方式
2021/04/01 Python
简单介绍Python的第三方库yaml
2021/06/18 Python
python机器学习Github已达8.9Kstars模型解释器LIME
2021/11/23 Python
python实现会员信息管理系统(List)
2022/03/18 Python