Nodejs mongoose中想用where a_ids in aArray 或者 b_ids in bArray能办到吗?
Nodejs mongoose中想用where a_ids in aArray 或者 b_ids in bArray能办到吗?
请问我用mongoose的话,想用where a_ids in aArray 或者 b_ids in bArray 或者c_ids in cArray,我刚用$where试了下失败了,代码如下,希望帮忙看看怎么整比较好。
var line = "";
if(uids.length > 0){
line += "createby.uid in [" + uids + "]";
}
if(gids.length > 0){
line += " || createby.gid in [" + gids + "]";
}
if(tids.length > 0){
line += " || createby.tid in [" + tids + "]";
}
message.find({}).$where(line).setOptions(optionObj).exec(function(err, messages){
callback_(err, messages);
});
当然可以实现这样的查询。在 Mongoose 中,你可以使用 $in
操作符来检查一个数组中的值是否包含在另一个数组中。你提到的 a_ids in aArray
和 b_ids in bArray
可以通过这种方式来实现。
以下是示例代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 假设我们有一个消息模型
const MessageSchema = new Schema({
a_ids: [{ type: Schema.Types.ObjectId }],
b_ids: [{ type: Schema.Types.ObjectId }],
// 其他字段...
});
const Message = mongoose.model('Message', MessageSchema);
// 查询条件
const aArray = ['a1', 'a2']; // 这里是你的aArray
const bArray = ['b1', 'b2']; // 这里是你的bArray
// 使用 $in 操作符进行查询
Message.find({
$or: [
{ a_ids: { $in: aArray } },
{ b_ids: { $in: bArray } }
]
}).then(messages => {
console.log(messages);
}).catch(err => {
console.error(err);
});
解释
$or
操作符:用于表示逻辑“或”操作。在这个例子中,它表示满足a_ids
在aArray
中或者b_ids
在bArray
中的文档。$in
操作符:用于检查一个字段是否包含在一个数组中。在这个例子中,它用于检查a_ids
是否包含在aArray
中,或者b_ids
是否包含在bArray
中。
注意事项
- 确保
aArray
和bArray
是数组类型,并且包含的是你要匹配的值。 - 如果你需要处理更多的数组(例如
c_ids
),只需在$or
条件中添加更多类似的条件即可。
这样,你就可以实现类似于 SQL 中的 IN
子句的功能,而不需要使用 $where
。
你说的这个api上有的,你的用法已经很接近了。代码如下
message.find().where('createby.uid').in(uids).exec(function(err,messages){
});
另外有些编辑器会给你报错,说in是一个关键字,这个你可以忽略。 where错误的用法是
message.find().where('createby.uid',uids).exec(function(err,messages){
});
因为此时他仅仅只能把你拼装好的uids当作是一个值来与数据库的createby.uid做比较,他是不知道你是要做数组的exists比较的。 要使用多个where-in判断,他们之间的关系是and,因此可以直接连接写
message.find()
.where('createby.uid').in(uids)
.where('createby.gid').in(gids)
.where('createby.tid').in(tids)
.exec(function(err,messages){
});
但是如果他们之间的关系是or,也许你在想是不是要用如下代码
message.find()
.where('createby.uid').in(uids).or()
.where('createby.gid').in(gids).or()
.where('createby.tid').in(tids)
.exec(function(err,messages){
});
答案是错的,or后面只支持对象数组,因此不可以这么添加,但是非要用你这样的搜索怎么办?mongoose本身是提供了原生搜索方法的,查阅mongoose-api和mongodb-api,你甚至能发现很多方法相同或者配置项相同的单词,OK你没有看错,他们确实有很多共同点。直接告诉你答案吧,按照你的思路,代码如下
message
.find()
.or([
{'createby.uid':{$in:[uids]}},
{'createby.tid':{$in:[tids]}},
{'createby.gid':{$in:[gids]}}
])
.exec(function(err,messages){
});
关键地方就是那个$in,记得官网有提过,这种写法是不安全的,他们也正在做改进,有些原生的写法是在api上被移除,但仍然可以使用,使用用风险,需要多注意。举个一般的例子,假设某个脑残程序员为了简单,未做任何处理,写了这样的查询代码
var id = req.param.id;
dao.find({id:id},function(err,docs){
});
看似没问题吧,有问题,数据的安全性有可能被暴露,预想提交的数据是
data:{id:'123'}
,但是实际可能提交的数据是data:{id:{$ne:'123'}}
。ok,这就意味着你的程序会查询所有id不是123的doc,数据的安全性被攻破,而且数据量过大的时候会导致服务器崩溃。 要等解决这种问题,就只能等官方进一步优化,移除配置项。
大神! 太感谢你了! 早上上班能看到这个真是叫人无比激动啊! 哈哈 谢啦 mongoose的where(“createby.uid”).in(uids)这个用法我也考虑过,但是想想要实现会比较麻烦,然后就想试试mongoose提供的$where的方式,可惜失败了。但是没有想到最后第二段你提到的那种原生态方式。另外有一个疑问,我也知道dao.find({id: id})这种写法不好,但是为啥实际提交的数据会变成data:{id:{$ne:‘123’}}呢? 求大神指点
假设这个脑残的程序员想解决这个问题,需要怎么做呢?
你可以使用Mongoose的查询条件来实现a_ids
在 aArray
中或者 b_ids
在 bArray
中。Mongoose 提供了 $in
操作符来检查某个字段的值是否在给定数组中。
以下是一个示例代码:
const message = require('./models/Message'); // 假设你的模型名为Message
// 假设 aArray 和 bArray 已经定义好了
const aArray = [1, 2, 3];
const bArray = [4, 5, 6];
message.find({
$or: [
{ a_ids: { $in: aArray } },
{ b_ids: { $in: bArray } }
]
}, function (err, messages) {
if (err) {
console.error(err);
return;
}
console.log(messages);
});
在这个示例中,我们使用了 $or
来组合两个查询条件。第一个条件检查 a_ids
是否在 aArray
中,第二个条件检查 b_ids
是否在 bArray
中。这样就可以满足你的需求了。
注意:如果你有更多的条件(比如 c_ids in cArray
),可以继续在 $or
数组中添加更多条件。