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 相关文章推荐
基于jQuery实现表格数据的动态添加与统计的代码
Jan 31 Javascript
javascript利用apply和arguments复用方法
Nov 25 Javascript
window.returnValue使用方法示例介绍
Jul 03 Javascript
通过jquery 获取URL参数并进行转码
Aug 18 Javascript
js读取cookie方法总结
Oct 31 Javascript
js面向对象之公有、私有、静态属性和方法详解
Apr 17 Javascript
webpack常用配置项配置文件介绍
Nov 07 Javascript
EditPlus中的正则表达式 实战(4)
Dec 15 Javascript
javascript笔记之匿名函数和闭包
Feb 06 Javascript
以BootStrap Tab为例写一个前端组件
Jul 25 Javascript
javaScript实现滚动条事件详解
Mar 24 Javascript
JS/CSS实现字符串单词首字母大写功能
Sep 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
c#中的实现php中的preg_replace
2009/12/21 PHP
dedecms中使用php语句指南
2014/11/13 PHP
php表单提交实例讲解
2015/11/12 PHP
yii数据库的查询方法
2015/12/28 PHP
PHPCMS V9 添加二级导航的思路详解
2016/10/20 PHP
PHP基于Redis消息队列实现发布微博的方法
2017/05/03 PHP
fancybox modal的完美解决(右上的X)
2012/10/30 Javascript
js onload事件不起作用示例分析
2013/10/09 Javascript
javascript实现window.print()去除页眉页脚
2014/12/30 Javascript
jQuery 判断图片是否加载完成方法汇总
2015/08/10 Javascript
纯javascript移动优先的幻灯片效果
2015/11/02 Javascript
分享网页检测摇一摇实例代码
2016/01/14 Javascript
JavaScript知识点总结(五)之Javascript中两个等于号(==)和三个等于号(===)的区别
2016/05/31 Javascript
模仿password输入框的实现代码
2016/06/07 Javascript
在Vue中使用this.$store或者是$route一直报错的解决
2019/11/08 Javascript
vue中的计算属性和侦听属性
2020/11/06 Javascript
用python实现的可以拷贝或剪切一个文件列表中的所有文件
2009/04/30 Python
python里将list中元素依次向前移动一位
2014/09/12 Python
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
2015/05/22 Python
Python实现简单的四则运算计算器
2016/11/02 Python
Python用zip函数同时遍历多个迭代器示例详解
2016/11/14 Python
Python深入06——python的内存管理详解
2016/12/07 Python
Python处理XML格式数据的方法详解
2017/03/21 Python
python实现单线程多任务非阻塞TCP服务端
2017/06/13 Python
python虚拟环境的安装配置图文教程
2017/10/20 Python
Python OpenCV处理图像之图像直方图和反向投影
2018/07/10 Python
pytorch训练imagenet分类的方法
2018/07/27 Python
Django使用Celery加redis执行异步任务的实例内容
2020/02/20 Python
Python使用ElementTree美化XML格式的操作
2020/03/06 Python
新加坡第一的杂货零售商:NTUC FairPrice
2020/12/05 全球购物
中国梦口号
2014/06/13 职场文书
阅兵口号
2014/06/19 职场文书
开展党的群众路线教育实践活动工作总结
2014/11/05 职场文书
防震减灾主题班会
2015/08/14 职场文书
python中的None与NULL用法说明
2021/05/25 Python
Prometheus 监控MySQL使用grafana展示
2021/08/30 MySQL