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 相关文章推荐
doctype后如何获得body.clientHeight的方法
Jul 11 Javascript
网页中CDATA标记的说明
Sep 12 Javascript
JS字符串累加Array不一定比字符串累加快(根据电脑配置)
May 14 Javascript
JavaScript实现函数返回多个值的方法
Jun 09 Javascript
深入浅析JavaScript中prototype和proto的关系
Nov 15 Javascript
jquery ztree实现树的搜索功能
Feb 25 Javascript
JS组件系列之Bootstrap table表格组件神器【终结篇】
May 10 Javascript
JavaScript获取tr td 的三种方式全面总结(推荐)
Aug 15 Javascript
react 创建单例组件的方法
Apr 26 Javascript
解决vue打包css文件中背景图片的路径问题
Sep 03 Javascript
springboot+vue实现文件上传下载
Nov 17 Vue.js
vite2.0+vue3移动端项目实战详解
Mar 03 Vue.js
深入浅析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
星际争霸任务指南——神族
2020/03/04 星际争霸
PHP分页类集锦
2014/11/18 PHP
PHP 绘制网站登录首页图片验证码
2016/04/12 PHP
PHP基于socket实现的简单客户端和服务端通讯功能示例
2017/07/10 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
Laravel下生成验证码的类
2017/11/15 PHP
Laravel如何创建服务器提供者实例代码
2019/04/15 PHP
javascript 页面只自动刷新一次
2009/07/10 Javascript
json数据的列循环示例
2013/09/06 Javascript
纯js和css实现渐变色包括静态渐变和动态渐变
2014/05/29 Javascript
ExtJs动态生成treepanel的Json格式
2015/07/19 Javascript
jQuery实现图片左右滚动特效
2020/04/20 Javascript
JQuery.Ajax()的data参数类型实例详解
2015/11/20 Javascript
jquery悬浮提示框完整实例
2016/01/13 Javascript
JS工作中的小贴士之”闭包“与事件委托的”阻止冒泡“
2016/06/16 Javascript
js 上传文件预览的简单实例
2016/08/16 Javascript
js中事件对象和事件委托的介绍
2019/01/21 Javascript
关于vue-cli 3配置打包优化要点(推荐)
2019/04/22 Javascript
[05:05]第三天的dota2
2013/07/29 DOTA
详解Python迭代和迭代器
2016/03/28 Python
python里使用正则表达式的组嵌套实例详解
2017/10/24 Python
Python定时任务sched模块用法示例
2018/07/16 Python
使用python对文件中的数值进行累加的实例
2018/11/28 Python
Python字典底层实现原理详解
2019/12/18 Python
Python 在函数上添加包装器
2020/07/28 Python
基于Python pyecharts实现多种图例代码解析
2020/08/10 Python
Delphi笔试题
2016/11/14 面试题
酒店应聘自荐信
2013/11/09 职场文书
装配出错检讨书
2014/09/23 职场文书
教师党员批评与自我批评
2014/10/15 职场文书
仓库保管员岗位职责
2015/02/09 职场文书
2015初中团支部工作总结
2015/07/21 职场文书
2015年治庸问责工作总结
2015/07/27 职场文书
2015年学校消防安全工作总结
2015/10/14 职场文书
OpenCV绘制圆端矩形的示例代码
2021/08/30 Python
Python tensorflow卷积神经Inception V3网络结构
2022/05/06 Python