node.js - MongoDB聚合: any value of $exists

标签 node.js mongodb express mongoose aggregation-framework

我正在尝试利用 MongoDB 聚合来实现 RESTful api,但遇到了以下情况。假设我有 Subscriptions 模型,如下所示:

var mongoose = require('mongoose'),
  Schema = mongoose.Schema;

var SubscriptionSchema = new Schema({
  // ...
  cancelled: Date
});

如果订阅处于事件状态,此已取消属性可以是未定义,也可以成为用户取消操作的日期

现在,我有一个路由GET/me/subscriptions,它聚合订阅并具有一个可选查询参数:cancelled=true(仅显示已取消)或cancelled=false(仅显示事件)。如果未指定,应返回任何订阅(事件或取消)。

var express = require('express'),
  router = express.Router(),
  Subscription = require('../../models/subscription');

router.get('/me/subscriptions', function(req, res, next) {
  var cancelled = req.query.cancelled === 'true' ? { $exists: true } :
    req.query.cancelled === 'false' ? { $exists: false } :
    { $exists: { $or: [ true, false ] } }; // wrong logic here

  return Subscription.aggregate([
      { $match: { user: req.user._id, cancelled: cancelled }},
      { $project: {
        // ...
      }}
    ])
    .exec()
    // ...
});

module.exports = router;

如果我传递上述查询参数,它会完美工作,但如果未指定参数(或者不等于 truefalse),则无法找到模型。我尝试了很多东西,而不是错误的行(在 $match 管道中):

cancelled: {}
cancelled: void 0
cancelled: { $exists: { $or: [ true, false ] } }
cancelled: { $exists: { $in: [ true, false ] } }
cancelled: { $exists: [ true, false ] } // obviously wrong, but hey
cancelled: null // obviously wrong, too
cancelled: { $or: [ { $exists: false }, { $exists: true } ] } // can't use $or here, but still, hey

现在看到的唯一解决方案是这样的,与一个不是未定义且不是Date类型的值进行比较,但这似乎太hacky了。

cancelled: { $ne: 'some-impossible-value' }

非常感谢任何帮助。

最佳答案

我认为稍微调整一下就可以满足您想要的条件。

var express = require('express'),
  router = express.Router(),
  Subscription = require('../../models/subscription');

router.get('/me/subscriptions', function(req, res, next) {
  var match_query = {user: req.user._id};

  if (req.query.cancelled === 'true') {
      match_query.cancelled = {$exists:true};
  } else if(req.query.cancelled === 'false') {
      match_query.cancelled = {$exists:false};
  }

  return Subscription.aggregate([
      { $match: match_query},
      { $project: {
        // ...
      }}
    ])
    .exec()
    // ...
});

module.exports = router;

您不需要添加 { $exists: { $or: [ true, false ] } ,如果您没有得到 true 或 false,则不要添加任何内容来查询。

我还没有检查代码是否有语法错误,但从逻辑上讲它会起作用。

关于node.js - MongoDB聚合: any value of $exists,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40021691/

相关文章:

javascript - 为什么我的解构失败了?

node.js - 我已经用brew更新了yarn,但我无法再运行yarn命令

mongodb - 更新 MongoDB 中精确元素数组中的字段

javascript - 在启用监视和启动服务器的情况下运行 webpack

Node.js/Express - 通过请求/响应对象修改响应模板上下文

javascript - 如何从 JSON 对象中获取值?

node.js - Windows 7 上的 Node 故障

javascript - Node js + Mysql : cannot enqueue because of fatal errors

python - 使用 pymongo 时使用字典键作为 _id

mysql - mongo 中的 mysql 日期函数等效吗?