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中的apply()方法和call()方法使用介绍
Jul 25 Javascript
jquery聚焦文本框与扩展文本框聚焦方法
Oct 12 Javascript
如何编写高质量JS代码
Dec 28 Javascript
AngularJS使用angular-formly进行表单验证
Dec 27 Javascript
jQuery源码分析之init的详细介绍
Feb 13 Javascript
关于react-router的几种配置方式详解
Jul 24 Javascript
vue自定义指令directive实例详解
Jan 17 Javascript
浅谈手写node可读流之流动模式
Jun 01 Javascript
JS中的防抖与节流及作用详解
Apr 01 Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
Jun 10 Javascript
通过循环优化 JavaScript 程序
Jun 24 Javascript
微信小程序全局变量改变监听的实现方法
Jul 15 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
印尼林东PWN黄金曼特宁咖啡豆:怎么冲世界上最醇厚的咖啡冲煮教程
2021/03/03 冲泡冲煮
不用iconv库的gb2312与utf-8的互换函数
2006/10/09 PHP
如何使用GDB调试PHP程序
2015/12/08 PHP
phpinfo() 中 Local Value(局部变量)Master Value(主变量) 的区别
2016/02/03 PHP
基于PHP实现微信小程序客服消息功能
2019/08/12 PHP
获取HTML DOM节点元素的方法的总结
2009/08/21 Javascript
编写Js代码要注意的几条规则
2010/09/10 Javascript
基于jquery封装的一个js分页
2011/11/15 Javascript
js检验密码强度(低中高)附图
2014/06/05 Javascript
node.js中的console.info方法使用说明
2014/12/09 Javascript
Javascript中数组方法汇总(推荐)
2015/04/01 Javascript
JavaScript模拟深蓝vs卡斯帕罗夫的国际象棋对局示例
2015/04/22 Javascript
javascript+HTML5的canvas实现七夕情人节3D玫瑰花效果代码
2015/08/04 Javascript
javascript for-in有序遍历json数据并探讨各个浏览器差异
2015/11/30 Javascript
jQuery基于扩展实现的倒计时效果
2016/05/14 Javascript
jQuery简单实现中间浮窗效果
2016/09/04 Javascript
jQuery插件ajaxFileUpload使用实例解析
2016/10/19 Javascript
Bootstrap笔记—折叠实例代码
2017/03/13 Javascript
JavaScript之事件委托实例(附原生js和jQuery代码)
2017/07/22 jQuery
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
2020/05/31 Javascript
寻找网站后台地址的python脚本
2014/09/01 Python
python通过索引遍历列表的方法
2015/05/04 Python
python opencv之分水岭算法示例
2018/02/24 Python
Django实现登录随机验证码的示例代码
2018/06/20 Python
Python实现求解一元二次方程的方法示例
2018/06/20 Python
Tornado Web Server框架编写简易Python服务器
2018/07/28 Python
Pandas GroupBy对象 索引与迭代方法
2018/11/16 Python
Python爬虫文件下载图文教程
2018/12/23 Python
python在OpenCV里实现投影变换效果
2019/08/30 Python
python写一个随机点名软件的实例
2019/11/28 Python
html5使用canvas实现弹幕功能示例
2017/09/11 HTML / CSS
若干个Java基础面试题
2015/05/19 面试题
缓刑人员的思想汇报
2014/01/11 职场文书
创建青年文明号材料
2014/05/09 职场文书
2015年学校食堂工作总结
2015/04/22 职场文书