Reputation: 41
I'm trying to find a user inside of an array of users who have the same id as the one in my token and access greater than 1.
to do so I'm using the following code but I'm getting a CastError:
Project.findOne({ Users: {User: decoded._id, access: { $gte: authStatus }}, _id: id })
.then((result) => {
console.log(result)
})
.catch((err) => {
console.log(err)
});
My Schema:
const ProjectSchema = new Schema(
{
Users: [
{
User: { type: mongoose.Schema.Types.ObjectId, ref: 'usertemps' },
access: { type: Number, required: true }
}
],
name: { type: String, required: true },
deadline: { type: Date, required: true }
},
{
timestamps: true
}
);
CastError:
CastError: Cast to Number failed for value "{ '$gte': 1 }" at path "access" for model "Projekt"
at model.Query.exec (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\query.js:4371:21)
at model.Query.Query.then (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\query.js:4463:15)
at validateOwner (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\routes\modules\verifyAccess.js:10:5)
at C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\routes\project.route.js:44:33
at Layer.handle [as handle_request] (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\route.js:137:13)
at module.exports (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\routes\modules\verifyToken.js:11:3)
at Layer.handle [as handle_request] (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\index.js:281:22
at param (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\index.js:354:14)
at param (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\index.js:365:14)
at Function.process_params (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\index.js:410:3)
at next (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\express\lib\router\index.js:275:10) {
messageFormat: undefined,
stringValue: `"{ '$gte': 1 }"`,
kind: 'Number',
value: { '$gte': 1 },
path: 'access',
reason: AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(!isNaN(val))
at castNumber (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\cast\number.js:28:10)
at SchemaNumber.cast (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\schema\number.js:382:12)
at SchemaNumber.SchemaType.applySetters (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\schematype.js:1075:12)
at EmbeddedDocument.$set (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\document.js:1250:20)
at EmbeddedDocument._handleIndex (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\document.js:1019:14)
at EmbeddedDocument.$set (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\document.js:960:22)
at EmbeddedDocument.Document (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\document.js:150:12)
at EmbeddedDocument [as constructor] (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\types\embedded.js:42:12)
at new EmbeddedDocument (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\schema\documentarray.js:115:17)
at DocumentArrayPath.SchemaArray.castForQuery (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\schema\array.js:485:13)
at DocumentArrayPath.SchemaType.castForQueryWrapper (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\schematype.js:1477:20)
at cast (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\cast.js:274:34)
at model.Query.Query.cast (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\query.js:4772:12)
at model.Query.Query._castConditions (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\query.js:1872:10)
at model.Query.<anonymous> (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\query.js:2129:8)
at model.Query._wrappedThunk [as _findOne] (C:\Users\tomod\OneDrive\Dokumenter\GitHub\Project-Manager-Project\node_modules\mongoose\lib\helpers\query\wrapThunk.js:16:8) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
}
}
Is it possible to do it this way or am I going about this all wrong?
Hope someone can help thanks for your time.
Upvotes: 1
Views: 1662
Reputation: 2011
In order to query nested fields, you should use the dot notation.
Project.findOne({
"Users.User": decoded._id,
"Users.access": { $gte: authStatus },
_id: id,
})
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
Edit:
In order to filter the elements inside an array and return only the elements that match certain condition, you can use $filter
operator
Project.aggregate([
{ $match: { _id: mongoose.Types.ObjectId(id) } },
{
$project: {
name: 1,
deadline: 1,
Users: {
$filter: {
input: "$Users",
as: "user",
cond: {
$and: [
{
$eq: ["$$user.User", mongoose.Types.ObjectId(decoded._id)],
},
{ $gte: ["$$user.access", authStatus] },
],
},
},
},
},
},
])
.then((result) => {
// Aggregate method only returns an array, since we are doing a $match based on _id,
// we can take the first element in the array if present
if (result && result.length) {
console.log(result[0]);
}
})
.catch((err) => {
console.log(err);
});
Upvotes: 4