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 将元素显示在屏幕的中央的代码
Feb 27 Javascript
移动节点的jquery代码
Jan 13 Javascript
javascript的propertyIsEnumerable()方法使用介绍
Apr 09 Javascript
学习JavaScript设计模式(多态)
Nov 25 Javascript
jQuery使用$.ajax进行异步刷新的方法(附demo下载)
Dec 04 Javascript
很棒的js选项卡切换效果
Jul 15 Javascript
js验证真实姓名与身份证号,手机号的简单实例
Jul 18 Javascript
详解javascript立即执行函数表达式IIFE
Feb 13 Javascript
深入理解Javascript中的观察者模式
Feb 20 Javascript
Vue0.1的过滤代码如何添加到Vue2.0直接使用
Aug 23 Javascript
vue中格式化时间过滤器代码实例
Apr 17 Javascript
Javascript和jquery在selenium的使用过程
Oct 31 jQuery
深入浅析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/07/04 PHP
php和数据库结合的一个简单的web实例 代码分析 (php初学者)
2011/07/28 PHP
destoon二次开发模板及调用语法汇总
2014/06/21 PHP
PHP strip_tags保留多个HTML标签的方法
2016/05/22 PHP
php使用pdo连接sqlite3的配置示例
2016/05/27 PHP
如何在Laravel5.8中正确地应用Repository设计模式
2019/11/26 PHP
基于jquery的jqDnR拖拽溢出的修改
2011/02/12 Javascript
对javascript的一点点认识总结《javascript高级程序设计》读书笔记
2011/11/30 Javascript
js中如何把字符串转化为对象、数组示例代码
2013/07/17 Javascript
深入理解javascript变量声明
2014/11/20 Javascript
jQuery toggle 代替方法
2016/03/22 Javascript
Javascript实现鼠标框选操作  不是点击选取
2016/04/14 Javascript
全面解析JavaScript的Backbone.js框架中的Router路由
2016/05/05 Javascript
原生js实现电商侧边导航效果
2017/01/19 Javascript
jQuery窗口拖动功能的实现代码
2017/02/04 Javascript
js获取文件里面的所有文件名(实例)
2017/10/17 Javascript
微信小程序input框中加入小图标的实现方法
2018/06/19 Javascript
vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)
2019/10/15 Javascript
[01:25:38]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第一场 1月19日
2021/03/11 DOTA
Python获取单个程序CPU使用情况趋势图
2015/03/10 Python
详解Django缓存处理中Vary头部的使用
2015/07/24 Python
微信跳一跳游戏python脚本
2020/04/01 Python
Python图像处理之简单画板实现方法示例
2018/08/30 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
深入理解Django-Signals信号量
2019/02/19 Python
Python模拟登录之滑块验证码的破解(实例代码)
2019/11/18 Python
Python字符串中删除特定字符的方法
2020/01/15 Python
无惧面试,带你搞懂python 装饰器
2020/08/17 Python
Python字符串的15个基本操作(小结)
2021/02/03 Python
移动端解决悬浮层(悬浮header、footer)会遮挡住内容的3种方法
2015/03/27 HTML / CSS
HTML5高仿微信聊天、微信聊天表情|对话框|编辑器功能
2018/04/23 HTML / CSS
提供世界各地便宜的机票:Sky-tours
2016/07/21 全球购物
NYX Professional Makeup英国官网:美国平价专业彩妆品牌
2019/11/13 全球购物
车间班长岗位职责
2013/11/30 职场文书
新年晚会主持词开场白
2015/05/28 职场文书
疑《守望先锋2》A测截图泄露 或将推出新模式、新界面
2022/04/03 其他游戏