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中dialog属性小记
Sep 03 Javascript
javascript学习笔记(七)利用javascript来创建和存储cookie
Apr 08 Javascript
jQuery图片预加载 等比缩放实现代码
Oct 04 Javascript
jQuery实现密保互斥问题解决方案
Aug 16 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
Sep 04 Javascript
Jquery修改页面标题title其它JS失效的解决方法
Oct 31 Javascript
Lab.js初次使用笔记
Feb 28 Javascript
Javascript将数值转换为金额格式(分隔千分位和自动增加小数点)
Jun 22 Javascript
jQuery+CSS实现的table表格行列转置功能示例
Jan 08 jQuery
旺旺在线客服代码 旺旺客服代码生成器
Jan 09 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
Feb 23 Javascript
使用Mock.js生成前端测试数据
Dec 13 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 MsSql server时遇到的中文编码问题
2009/06/11 PHP
高性能PHP框架Symfony2经典入门教程
2014/07/08 PHP
async和DOM Script文件加载比较
2014/07/20 PHP
任意位置显示html菜单
2007/02/01 Javascript
写出更好的JavaScript之undefined篇(上)
2009/11/22 Javascript
jQuery随机切换图片的小例子
2013/04/18 Javascript
window.onresize 多次触发的解决方法
2013/11/08 Javascript
Javascript call和apply区别及使用方法
2013/11/14 Javascript
浅析Cookie中的Path与domain
2013/12/18 Javascript
Js实现网页键盘控制翻页的方法
2014/10/30 Javascript
jQuery控制cookie过期时间的方法
2015/04/07 Javascript
浅谈jQuery中replace()方法
2015/05/13 Javascript
关于Vue.js一些问题和思考学习笔记(2)
2016/12/02 Javascript
Extjs 中的 Treepanel 实现菜单级联选中效果及实例代码
2017/08/22 Javascript
BootStrap实现文件上传并带有进度条效果
2017/09/11 Javascript
vue+node+webpack环境搭建教程
2017/11/05 Javascript
在 React、Vue项目中使用SVG的方法
2018/02/09 Javascript
Vue项目中使用Vux的安装过程
2018/05/01 Javascript
详解各版本React路由的跳转的方法
2018/05/10 Javascript
微信小程序实现发微博功能的示例代码
2020/06/24 Javascript
详解vue 组件的实现原理
2020/11/12 Javascript
python对list中的每个元素进行某种操作的方法
2018/06/29 Python
python3使用GUI统计代码量
2019/09/18 Python
python获取依赖包和安装依赖包教程
2020/02/13 Python
Python基于内置库pytesseract实现图片验证码识别功能
2020/02/24 Python
python 线性回归分析模型检验标准--拟合优度详解
2020/02/24 Python
python访问hdfs的操作
2020/06/06 Python
Python识别验证码的实现示例
2020/09/30 Python
施华洛世奇意大利官网:SWAROVSKI意大利
2018/07/23 全球购物
俄罗斯电子产品在线商店:UltraTrade
2020/01/30 全球购物
百度软件工程师职位
2013/02/14 面试题
小学生放飞梦想演讲稿
2014/08/26 职场文书
2015年社区文体活动总结
2015/03/25 职场文书
会计做账心得体会
2016/01/22 职场文书
Python爬虫框架之Scrapy中Spider的用法
2021/06/28 Python
java objectUtils 使用可能会出现的问题
2022/02/28 Java/Android