【问题标题】:Is there an alternative for $expr in older versions of MongoDB? [duplicate]在旧版本的 MongoDB 中是否有 $expr 的替代方案? [复制]
【发布时间】:2019-03-21 01:42:01
【问题描述】:

在 React.js 应用程序的 Node.js 后端中,我正在使用

"mongodb" (as db.version returns): "3.4.10",
"mongoose": "5.3.4"

问题是我不能将 $expr 与 mongoDB 版本

代码如下:

match.$expr = {
            $lt: ["$distance", "$range"] // "calculated_distance < tutor_range"
         }

你知道怎么做吗?这是完整的方法,如果您想了解更多详细信息。

exports.search = (req, res) => {
  let lat1 = req.body.lat;
  let lon1 = req.body.lng;
  let page = req.body.page || 1;
  let perPage = req.body.perPage || 10;
  let radius = req.body.radius || 10000;

  let levelsIn = req.body.levels && req.body.levels.length !== 0 ? req.body.levels.map(level => {
    return ObjectID(level);
  }) : null;
  let subjectsIn = req.body.subjects && req.body.subjects.length !== 0 ? req.body.subjects.map(subject => {
    return ObjectID(subject);
  }) : null;

  var options = { page: page, limit: perPage,  sortBy: { updatedDate: -1 } }

  const isAdmin = req.user ? req.user.role === "admin" || req.user.role === "super-admin" : false;

  let match = {}

  if (levelsIn) match.levels = { $in: levelsIn };
  if (subjectsIn) match.subjects = { $in: subjectsIn }
  if (typeof req.body.activated !== "undefined") match.profileActivated = req.body.activated;
  if (req.body.from) match.createdAt = { $gte: new Date(req.body.from) };
  if (req.body.to) {
    if (match.createdAt) match.createdAt.$lte = new Date(req.body.to);
    else match.createdAt = { $lte: new Date(req.body.to) };
  }

  var aggregate = null;

  if (!isAdmin) {
    match.activated = true
    match.profileActivated = true
    match.profileOnline = true
  }

  if (lat1 && lon1) {

     match.$expr = {
        $lt: ["$distance", "$range"] // "calculated_distance < tutor_range"
     }

       aggregate = Tutor.aggregate([
     {

       "$geoNear": {
         "near": {
           "type": "Point",
           "coordinates": [lon1, lat1]
         },
         "distanceField": "distance", // this calculated distance will be compared in next section
         "distanceMultiplier": 0.001,
         "spherical": true
       }
     },
     {
       $match: match
     }
     ]);
  } else {
    aggregate = Tutor.aggregate([
      {
        $match: match
      }
    ]);
  }

  Tutor
    .aggregatePaginate(aggregate, options, function (err, result, pageCount, count) {
      if (err) {
        return res.status(400).send(err);
      }
      else {

        var opts = [
          { path: 'levels', select: 'name' },
          { path: 'subjects', select: 'name' },
          { path: 'assos', select: 'name' }
        ];
        Tutor
          .populate(result, opts)
          .then(result2 => {
            return res.send({
              page: page,
              perPage: perPage,
              pageCount: pageCount,
              documentCount: count,
              tutors: result2
            });
          })
          .catch(err => {
            return res.status(400).send(err);
          });
      }
    })
};

非常感谢您的回答和帮助!

【问题讨论】:

    标签: node.js mongodb mongoose aggregation-framework


    【解决方案1】:

    您可以使用$addFields + $match 代替$expr

    类似

    {"$addFields":{"islt":{"$cond":[{"$lt": ["$distance", "$range"]}, true, false]}}},
    {"$match":{"islt":true}}
    

    如果您愿意,可以使用额外的项目阶段来删除 islt 变量。

     {"$project":{"islt":0}}
    

    【讨论】:

    • 谢谢!!这行得通:)
    猜你喜欢
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 2013-12-22
    • 2017-03-21
    相关资源
    最近更新 更多