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做flash做的事..才完成的一个类.Auntion Action var 0.1
Feb 23 Javascript
jQuery EasyUI API 中文文档 - TreeGrid 树表格使用介绍
Nov 21 Javascript
Javascript 拖拽的一些简单的应用(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
JavaScript中的继承方式详解
Feb 11 Javascript
js实现鼠标经过时图片滚动停止的方法
Feb 16 Javascript
JavaScript中getUTCSeconds()方法的使用详解
Jun 11 Javascript
javascript如何定义对象数组
Jun 07 Javascript
javascript之IE版本检测超简单方法
Aug 20 Javascript
react-native fetch的具体使用方法
Nov 01 Javascript
JS与CSS3实现图片响应鼠标移动放大效果示例
May 04 Javascript
JS 中可以提升幸福度的小技巧(可以识别更多另类写法)
Jul 28 Javascript
Angular5中状态管理的实现
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
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
Json_encode防止汉字转义成unicode的方法
2016/02/25 PHP
Yaf框架封装的MySQL数据库操作示例
2019/03/06 PHP
ThinkPHP3.2.3框架实现执行原生SQL语句的方法示例
2019/04/03 PHP
JS 分号引起的一段调试问题
2009/06/18 Javascript
jquery加载页面的方法(页面加载完成就执行)
2011/06/21 Javascript
兼容主流浏览器的iframe自适应高度js脚本
2014/01/10 Javascript
使用Nodejs开发微信公众号后台服务实例
2014/09/03 NodeJs
JavaScript简介
2015/02/15 Javascript
基于JS实现的笛卡尔乘积之商品发布
2016/05/13 Javascript
AngularJS基础 ng-model-options 指令简单示例
2016/08/02 Javascript
JavaScript运动框架 解决防抖动问题、悬浮对联(二)
2017/05/17 Javascript
基于bootstrap实现多个下拉框同时搜索功能
2017/07/19 Javascript
Angular父子组件通过服务传参的示例方法
2018/10/31 Javascript
[01:18]PWL开团时刻DAY10——一拳超人
2020/11/11 DOTA
Python在不同目录下导入模块的实现方法
2017/10/27 Python
简述Python2与Python3的不同点
2018/01/21 Python
在python中将字符串转为json对象并取值的方法
2018/12/31 Python
python3 正则表达式基础廖雪峰
2020/03/25 Python
Keras保存模型并载入模型继续训练的实现
2021/02/20 Python
美国蔬菜和植物种子公司:Burpee
2017/02/01 全球购物
英国豪华真皮和布艺沙发销售网站:Darlings of Chelsea
2018/01/05 全球购物
苏格兰领先的多渠道鞋店:Begg Shoes
2019/10/22 全球购物
俄罗斯Sportmarket体育在线商店:用于旅游和户外活动
2019/11/12 全球购物
高中生自我评语大全
2014/01/19 职场文书
干部培训自我鉴定
2014/01/22 职场文书
《望洞庭》教学反思
2014/02/16 职场文书
贯彻学习两会心得体会范文
2014/03/17 职场文书
环保宣传标语
2014/06/12 职场文书
导航工程专业自荐信
2014/09/02 职场文书
新店开张宣传语
2015/07/13 职场文书
2015年大学迎新工作总结
2015/07/16 职场文书
大学生奖学金获奖感言(范文)
2019/08/15 职场文书
竞选稿之小学班干部
2019/10/31 职场文书
原型和原型链 prototype和proto的区别详情
2021/11/02 Javascript
Mybatis是这样防止sql注入的
2021/12/06 Java/Android