Reputation: 6257
I want to perform a query on a mongo database with three variables: age, job, and location as an option. I use Node and Express on the server side.
I have written this:
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" });
}
});
In case it might be helpful, here is the User Schema:
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);
The error is MongoError: unknown operator: $or
. How to properly retrieve an array of users that match the conditions expressed in the query?
Upvotes: 2
Views: 3373
Reputation: 17915
You need to replace job: { $or: job }
with job: { $in: job }
cause $in query operator validates a field's value against an array and get the documents if at least one of the element in the array matches with the field Vs $or logical operator takes in two expressions not the values and get the documents where at least one expressions is satisfied.
$in :
// jobs = ["Tech", "Sales"]
jobs: { $in: jobs }
Test : mongoplayground
$or :
{ $or: [ {jobs : 'Tech'} , {jobs : 'Sales'} ] }
Test : mongoplayground
As you're just validating against an array on same field you don't need $or
operator a simple $in
should work just fine. Moreover in $geoNear
you might need to replace coordinates: location.coordinates
with coordinates: location
- I believe it's a typo.
Upvotes: 2
Reputation: 14480
$or is an expression-level operator, not a field-level operator. The field-level equivalent of $or is $in.
Upvotes: 0