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 变量命名规则
Sep 23 Javascript
jquery中show()、hide()和toggle()用法实例
Jan 15 Javascript
angular2使用简单介绍
Mar 01 Javascript
JS实现页面中所有img对象添加onclick事件及新窗口查看图片的方法
Dec 27 Javascript
javascript 中的try catch应用总结
Apr 01 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
Dec 05 Javascript
Thinkjs3新手入门之如何使用静态资源目录
Dec 06 Javascript
如何安装控制器JavaScript生成插件详解
Oct 21 Javascript
利用Vue构造器创建Form组件的通用解决方法
Dec 03 Javascript
前端Electron新手入门教程详解
Jun 21 Javascript
javascript随机变色实例代码
Oct 15 Javascript
JavaScript实现4位随机验证码的生成
Jan 28 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
php下载远程文件类(支持断点续传)
2008/11/14 PHP
PHP+MYSQL会员系统的开发实例教程
2014/08/23 PHP
PHP实现基于栈的后缀表达式求值功能
2017/11/10 PHP
php表单处理操作
2017/11/16 PHP
番茄的表单验证类代码修改版
2008/07/18 Javascript
IE FF OPERA都可用的弹出层实现代码
2009/09/29 Javascript
JavaScript之引用类型介绍
2012/08/10 Javascript
JS 实现导航栏悬停效果(续)
2013/09/24 Javascript
JS简单随机数生成方法
2016/09/05 Javascript
js判断一个字符串是以某个字符串开头的简单实例
2016/12/27 Javascript
纯JS单页面赛车游戏制作代码分享
2017/03/03 Javascript
vue组件(全局,局部,动态加载组件)
2018/09/02 Javascript
详解Vue中watch对象内属性的方法
2019/02/01 Javascript
Jquery异步上传文件代码实例
2019/11/13 jQuery
js+css实现全屏侧边栏
2020/06/16 Javascript
使用Mock.js生成前端测试数据
2020/12/13 Javascript
Python Web框架Flask中使用百度云存储BCS实例
2015/02/08 Python
Hadoop中的Python框架的使用指南
2015/04/22 Python
centos6.7安装python2.7.11的具体方法
2017/01/16 Python
Python实现求笛卡尔乘积的方法
2017/09/16 Python
解决phantomjs截图失败,phantom.exit位置的问题
2018/05/17 Python
关于Pytorch MaxUnpool2d中size操作方式
2020/01/03 Python
如何定义TensorFlow输入节点
2020/01/23 Python
python实现提取str字符串/json中多级目录下的某个值
2020/02/27 Python
Python数组拼接np.concatenate实现过程
2020/04/18 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
2020/04/20 Python
将keras的h5模型转换为tensorflow的pb模型操作
2020/05/25 Python
怎么快速自学python
2020/06/22 Python
利用scikitlearn画ROC曲线实例
2020/07/02 Python
税务干部群众路线教育实践活动自我剖析材料
2014/09/21 职场文书
2016年感恩父亲节活动总结
2016/04/01 职场文书
Python自然语言处理之切分算法详解
2021/04/25 Python
pytorch常用数据类型所占字节数对照表一览
2021/05/17 Python
sql server删除前1000行数据的方法实例
2021/08/30 SQL Server
victoriaMetrics库布隆过滤器初始化及使用详解
2022/04/05 Golang
python中mongodb包操作数据库
2022/04/19 Python