#javascript #node.js #mongodb #mongoose
#javascript #node.js #mongodb #мангуста
Вопрос:
Я пытаюсь найти пользователя внутри массива пользователей, у которых тот же идентификатор, что и у моего токена, и доступ больше 1.
для этого я использую следующий код, но я получаю ошибку:
Project.findOne({ Users: {User: decoded._id, access: { $gte: authStatus }}, _id: id })
.then((result) => {
console.log(result)
})
.catch((err) => {
console.log(err)
});
Моя схема:
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: Cast to Number failed for value "{ '$gte': 1 }" at path "access" for model "Projekt"
at model.Query.exec (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibquery.js:4371:21)
at model.Query.Query.then (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibquery.js:4463:15)
at validateOwner (C:UserstomodOneDriveDokumenterGitHubProject-Manager-ProjectroutesmodulesverifyAccess.js:10:5)
at C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectroutesproject.route.js:44:33
at Layer.handle [as handle_request] (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterlayer.js:95:5)
at next (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterroute.js:137:13)
at module.exports (C:UserstomodOneDriveDokumenterGitHubProject-Manager-ProjectroutesmodulesverifyToken.js:11:3)
at Layer.handle [as handle_request] (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterlayer.js:95:5)
at next (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterroute.js:137:13)
at Route.dispatch (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterroute.js:112:3)
at Layer.handle [as handle_request] (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterlayer.js:95:5)
at C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterindex.js:281:22
at param (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterindex.js:354:14)
at param (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterindex.js:365:14)
at Function.process_params (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterindex.js:410:3)
at next (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesexpresslibrouterindex.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:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibcastnumber.js:28:10)
at SchemaNumber.cast (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibschemanumber.js:382:12)
at SchemaNumber.SchemaType.applySetters (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibschematype.js:1075:12)
at EmbeddedDocument.$set (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibdocument.js:1250:20)
at EmbeddedDocument._handleIndex (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibdocument.js:1019:14)
at EmbeddedDocument.$set (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibdocument.js:960:22)
at EmbeddedDocument.Document (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibdocument.js:150:12)
at EmbeddedDocument [as constructor] (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibtypesembedded.js:42:12)
at new EmbeddedDocument (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibschemadocumentarray.js:115:17)
at DocumentArrayPath.SchemaArray.castForQuery (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibschemaarray.js:485:13)
at DocumentArrayPath.SchemaType.castForQueryWrapper (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibschematype.js:1477:20)
at cast (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibcast.js:274:34)
at model.Query.Query.cast (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibquery.js:4772:12)
at model.Query.Query._castConditions (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibquery.js:1872:10)
at model.Query.<anonymous> (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibquery.js:2129:8)
at model.Query._wrappedThunk [as _findOne] (C:UserstomodOneDriveDokumenterGitHubProject-Manager-Projectnode_modulesmongooselibhelpersquerywrapThunk.js:16:8) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '=='
}
}
Возможно ли это сделать таким образом, или я все делаю неправильно?
Надеюсь, кто-нибудь сможет помочь, спасибо за ваше время.
Ответ №1:
Для запроса вложенных полей следует использовать точечную нотацию.
Project.findOne({
"Users.User": decoded._id,
"Users.access": { $gte: authStatus },
_id: id,
})
.then((result) => {
console.log(result);
})
.catch((err) => {
console.log(err);
});
Редактировать:
Чтобы отфильтровать элементы внутри массива и вернуть только те элементы, которые соответствуют определенному условию, вы можете использовать $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 amp;amp; result.length) {
console.log(result[0]);
}
})
.catch((err) => {
console.log(err);
});
Комментарии:
1. Я уже пробовал это, и это не сработало. Проблема в том, что мне нужно найти конкретного пользователя, у которого есть идентификатор, который я ищу, и достаточно высокое значение доступа. Если я использую точечную нотацию, она просто находит любого пользователя с идентификатором и любого пользователя с достаточно высоким значением доступа.
2. @MartinOlesen Насколько я понимаю, вам нужен только
Users
массив в результате, чтобы пользователи соответствовали условию. Я обновил ответ на основе этого. Пожалуйста, проверьте