node.js - 使用数组查询参数 Node/Mongoose 查询数组字段
问题描述
我有一个 Route 架构字段,它是一个字符串数组weekdays: {type:[String], required:false}
,可以包含 0 到 7 个字符串(使用天数),因此通过查询我还传递了一个数组(工作日范围)以查找工作日数组字段包含的任何记录至少一个查询工作日数组值。
我正在使用weekdays: {$elemMatch: {weekdays}
,但它不起作用,因为该字段应匹配所有条件,因此所有查询数组。我也尝试了$in
操作符,但它使节点崩溃并显示以下消息:
Mongoose Route.findRoutes city weekdays time ranges public error: CastError: Cast to string failed for value "{ weekdays: '[tue, wed, thu, fri, sat, sun]' }" (type Object) at path "weekdays" for model "Route"
at model.Query.exec (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:4470:21)
at model.Query.Query.find (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/query.js:2085:8)
at Function.find (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/model.js:2093:13)
at exports.findRoutes (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/api/src/controllers/route.controller.js:28:15)
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7
at Layer.handle [as handle_request] (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express/lib/router/layer.js:95:5)
at next (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express/lib/router/route.js:137:13)
at exports.clientApiKeyValidation (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/api/src/auth_utils.js:15:10)
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7
at handleReturn (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:24:23)
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express-promise-router/lib/express-promise-router.js:64:7
at Layer.handle [as handle_request] (/Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/express/lib/router/layer.js:95:5) {
messageFormat: undefined,
stringValue: `"{ weekdays: '[tue, wed, thu, fri, sat, sun]' }"`,
kind: 'string',
value: { weekdays: '[tue, wed, thu, fri, sat, sun]' },
path: 'weekdays',
reason: null,
valueType: 'Object'
}
node:events:346
throw er; // Unhandled 'error' event
^
TypeError: Cannot read property 'length' of undefined
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/api/src/controllers/route.controller.js:54:28
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/model.js:4868:18
at processTicksAndRejections (node:internal/process/task_queues:76:11)
Emitted 'error' event on Function instance at:
at /Volumes/ProjectsSSD/FixitServer/fixit_server_node/node_modules/mongoose/lib/model.js:4870:15
在这种情况下使用什么正确的运算符或者如何交叉检查两个数组?一如既往地感谢您的时间和帮助。
这是控制器中的方法:
if (city && region && country && isPublic && weekdays && minTime && maxTime) {
Route.find(
{
city: city,
region: region,
country: country,
isPublic: isPublic,
time: {
$gte: minTime,
$lte: maxTime
},
weekdays: {
$elemMatch: {
weekdays}
}
},
function (err, result) {
if (err) {
console.log('Mongoose Route.findRoutes city weekdays time ranges public error: ', err);
res.status(503).send({
error: 'Internal error'
});
}
if (result.length > 0) {
console.log('Mongoose Route.findRoutes city weekdays time ranges public: ', result);
res.status(200).send({
message: 'Routes found.',
data: result
});
} else {
console.log('Mongoose Route.findRoutes city weekdays time ranges public : No routes found.');
res.status(404).send({ message: 'No routes found' });
}
}
);
}
这是架构:
const routeSchema = new mongoose.Schema({
city: { type: String, required: true },
region: { type: String, required: true },
country: { type: String, required: true },
userName: { type: String, required: true },
routeName: { type: String, required: true },
routeDistance: { type: String, required: true },
routeDuration: { type: String, required: true },
rawTrack: { type: [Object], required: true },
// snappedToRoad: { type: [Object], required: false },
tracked: { type: [Object], required: false },
filtered: { type: [Object], required: false },
isPublic: {type: Boolean, required: false, default: false},
weekdays: {type:[String], required:false},
time : {type:String, required: false}
},
{
timestamps: true,
toObject: { virtuals: true },
toJSON: { virtuals: true }
});
解决方案
也许你使用了错误的语法,$in
因为在这种情况下它是正确的方法。如果你的weekdays
变量是一个数组,你可以使用下面的代码:
Route.find({
...
weekdays: { $in: weekdays },
...
})
推荐阅读
- excel - Excel中来自二维矩阵/数组的数据验证列表
- javascript - 有没有办法用空行分割多行的文本?
- haskell - 使用 mfix 避免无限递归
- java - 如何从不同的数据库中获取映射的实体?
- python - Telethon 在按钮之后写消息/开始聊天 - 机器人在 /start 之前发送消息
- javascript - 在 c# (Unity) 中解析 JSON 文件
- xcode - 在 Appstore 上将版本设置为仅限 iPad
- php - 从 Laravel 的下拉菜单中获取数据
- next.js - NextJS 拆分块缓存在开发模式下不起作用
- visual-studio-code - 如何使用我的自定义字符串修改 VSCode 中的第 3 行(n)和每个 n+6(如 9、15、24 等)?