【问题标题】:Mongoose aggregation: MongoError: unknown operator: $orMongoose 聚合:MongoError:未知运算符:$ 或
【发布时间】:2020-10-03 06:56:46
【问题描述】:

我想使用三个变量对 mongo 数据库执行查询:年龄、工作和位置作为选项。我在服务器端使用 Node 和 Express。

我写了这个:

router.post("/search", async (req, res) => {
  try {
    const { jobs, minAge, maxAge, location, maxDistance } = req.body;
   // jobs = ["Tech", "Sales"], minAge=45, maxAge = 62, location=[1.23, 4.56], maxDistance=10000 
    if (!location) {
      const user = User.aggregate([
        {$match: {
            jobs: { $or: jobs },
            age: { $gte: minAge, $lte: maxAge },
          }},
      ]).lean()
       return res.json({user})
      });
    }
 
    const user = User.aggregate([
     { $match: {
      job: { $or: job },
      age: { $gte: minAge, $lte: maxAge }
      },
        $geoNear: {
          near: { type: "Point", coordinates: location.coordinates },
          distanceField: "dist.calculated",
          maxDistance,
        },
      },
    ]).lean();
    return res.json({ user });
  } catch (err) {
    return res.json({ errorType: "search" });
  }
});

如果有帮助,这里是用户架构:

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema(
  {
    username: { type: String, required: true, unique: true },
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    age: { type: Number, min: 18 },
    job: {
      type: String,
      enum: ["Tech", "Product", "Marketing", "Sales", "HR", "Other"],
    },
    location: {
      type: { type: String, enum: ["Point"] },
      coordinates: { type: [Number] },
    },
  },
  { timestamps: true }
);

userSchema.index({ age: 1, job: 1, location: "2dsphere" });

module.exports = mongoose.model("User", userSchema);

错误是MongoError: unknown operator: $or。如何正确检索与查询中表达的条件匹配的用户数组?

【问题讨论】:

  • 据我了解,您需要从array 匹配jobs。然后你可以使用$in 而不是$or
  • 我需要返回其工作是查询数组中定义的工作之一的用户。
  • @DoneDeal0 :您需要将job: { $or: job } 替换为job: { $in: job } 以获得所需的结果,这里near: { type: "Point", coordinates: location.coordinates } 不是coordinates: location 吗?

标签: node.js mongodb express mongoose


【解决方案1】:

$or is an expression-level operator,不是字段级运算符。 $or 的字段级等价物是$in

【讨论】:

    【解决方案2】:

    您需要将job: { $or: job } 替换为job: { $in: job },因为$in 查询运算符会根据数组验证字段的值,并在数组中至少有一个元素与字段匹配时获取文档Vs $or 逻辑运算符接受两个表达式而不是值,并获取至少满足一个表达式的文档。

    $in :

    // jobs = ["Tech", "Sales"]
    
    jobs: { $in: jobs }
    

    测试: mongoplayground

    $或:

    { $or: [ {jobs : 'Tech'} , {jobs : 'Sales'} ] }
    

    测试: mongoplayground

    由于您只是针对同一字段上的数组进行验证,因此您不需要 $or 运算符,一个简单的 $in 应该可以正常工作。此外,在$geoNear 中,您可能需要将coordinates: location.coordinates 替换为coordinates: location - 我认为这是一个错字。

    【讨论】:

    • @DoneDeal0 :如果您想了解更多关于差异的信息,请查看:stackoverflow.com/q/61948578/7237613
    • 感谢您的详细回答,非常感谢您的帮助。但是,它只能在没有 geonear 运算符的情况下工作。我确保在距离我的地理查询 1 公里范围内添加虚拟数据。然而,我收到“未定义”。是的,这是一个错字,我将位置发送为 [1.11, 2.22]。此外,从结果中排除执行请求的用户的最有效方法是什么?添加 _id: { $not: [user.id]} 或在结果出现后执行简单的 javascript 过滤器?
    • @DoneDeal0 : 我从来没有使用过$geoNear,请在上面发布一个新问题,有人可以帮助你。但是如果可能的话,宁愿从数据库中获取更少的数据,所以在这种情况下:_id 字段是自动索引的,在_id 上做一个简单的过滤器($match)是快速简单的,而不是将文档获取到 .Js 和迭代删除不必要的文档继续进行数据库查询..
    猜你喜欢
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 2019-03-27
    • 2021-07-10
    • 2021-06-16
    • 1970-01-01
    相关资源
    最近更新 更多