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 相关文章推荐
js 兼容多浏览器的回车和鼠标焦点事件代码(IE6/7/8,firefox,chrome)
Apr 14 Javascript
javascript高级学习笔记整理
Aug 14 Javascript
javascript中日期转换成时间戳的小例子
Mar 21 Javascript
使图片旋转的3种解决方案
Nov 21 Javascript
jquery用data方法获取某个元素上的事件
Jun 23 Javascript
javascript中的this详解
Dec 08 Javascript
javascript 动态创建表格
Jan 08 Javascript
JavaScript使用yield模拟多线程的方法
Mar 19 Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
Sep 18 Javascript
vue使用自定义指令实现拖拽
Jan 29 Javascript
Vue.extend 编程式插入组件的实现
Nov 18 Javascript
VUEX-action可以修改state吗
Nov 19 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数组 为文章加关键字连接 文章内容自动加链接
2011/12/29 PHP
php中用unset销毁变量并释放内存
2020/05/10 PHP
关于PhpStorm设置点击编辑文件自动定位源文件的实现方式
2020/12/30 PHP
JS实现self的resend
2010/07/22 Javascript
javascript学习笔记(五) Array 数组类型介绍
2012/06/19 Javascript
比较新旧两个数组值得增加和删除的JS代码
2013/10/30 Javascript
javascript鼠标滑动评分控件完整实例
2015/05/13 Javascript
JavaScript中继承用法实例分析
2015/05/16 Javascript
JS的框架Polymer中的dom-if和is属性使用说明
2015/07/29 Javascript
jquery trigger实现联动的方法
2016/02/29 Javascript
Easyui 之 Treegrid 笔记
2016/04/29 Javascript
jQuery插件开发汇总
2016/05/15 Javascript
原生JS实现在线问卷调查投票特效
2017/01/03 Javascript
Vue中保存数据到磁盘文件的方法
2018/09/06 Javascript
浅入深出Vue之自动化路由
2019/08/06 Javascript
[07:40]DOTA2每周TOP10 精彩击杀集锦vol.4
2014/06/25 DOTA
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
Python读写txt文本文件的操作方法全解析
2016/06/26 Python
浅谈Python中的可变对象和不可变对象
2017/07/07 Python
基于Python代码编辑器的选用(详解)
2017/09/13 Python
使用Python的package机制如何简化utils包设计详解
2017/12/11 Python
基于Django filter中用contains和icontains的区别(详解)
2017/12/12 Python
对Pycharm创建py文件时自定义头部模板的方法详解
2019/02/12 Python
python lambda函数及三个常用的高阶函数
2020/02/05 Python
Python 必须了解的5种高级特征
2020/09/10 Python
python3中calendar返回某一时间点实例讲解
2020/11/18 Python
基于DOM+CSS3实现OrgChart组织结构图插件
2016/03/02 HTML / CSS
HTML5中的新元素介绍
2008/10/17 HTML / CSS
波兰香水和化妆品购物网站:Notino.pl
2017/11/07 全球购物
化学学院毕业生自荐信范文
2013/12/17 职场文书
上海世博会口号
2014/06/19 职场文书
一年级小学生评语大全
2014/12/25 职场文书
公司处罚决定书
2015/06/24 职场文书
拔河比赛队名及霸气口号
2015/12/24 职场文书
Python爬虫:从m3u8文件里提取小视频的正确操作
2021/05/14 Python
MySQL 8.0 驱动与阿里druid版本兼容问题解决
2021/07/01 MySQL