Mongo: 查找不包含特定字段的项
在使用mongoose(v6)的过程中,如果尝试使用$exists来查找mongoose模式中未定义的字段,会发现mongoose v6会对其进行转义。这个问题的出现是因为mongoose v6移除了strictQuery选项,并用strict选项替代。在mongoose v6中,默认情况下,使用User.find({ notInSchema: 1 })查找会被过滤掉notInSchema字段。为了解决这个问题,可以通过设置strictQuery: false来允许过滤不在模式中的属性。
例如,可以按照以下方式定义用户模式和模型:
const userSchema = new Schema({ name: String }); const User = mongoose.model('User', userSchema);
默认情况下,User.find({ notInSchema: 1 })等同于User.find(),因为Mongoose会过滤掉不在模式中的字段。
要允许过滤不在模式中的字段,可以使用以下方法:
await User.find({ notInSchema: 1 }, null, { strictQuery: false }); // 或者等价写法 await User.find({ notInSchema: 1 }).setOptions({ strictQuery: false });
通过设置strictQuery: false,就可以解决在mongoose v6中使用$exists查找未定义字段的问题。
问题的出现原因是想要在Mongo数据库中查找没有特定字段的项。解决方法是使用查询条件{ $exists: false }
来查找没有特定字段的项。
在Mongo数据库中,如果字段缺失或为null
,可以使用db.things.find( { a : null } );
来查询。这种方法更安全,因为$exists
会返回true
,即使字段为null
,这通常不是期望的结果,并且可能导致空指针异常。
然而,有些人可能会将db.things.find( { a : null } );
解释为字段必须等于null
,而不是缺失。这种行为实际上是意外的,因为对于0
(也是false
),你不能做同样的操作,所以null
在这里是个例外。因此,最佳实践是使用更易读的$exists: false
,这样不会产生歧义。记住,如果需要在查询之后添加注释,那么稍微更短的变体其实并不更短!
如果目标是查找所有缺少字段a
值的对象,无论是因为a
为null
还是缺失,那么$exists
就不够用,因为它无法捕捉a
为null
的情况。
我认为最好的答案是使用{ $exists: false }
作为查询条件,因为它不会使用任何索引,而{ $eq: false }
如果有索引的话会使用索引。
MongoDB: 查找不包含特定字段的项
在MongoDB中,我们可以使用$exists操作符来实现该功能。当$exists为true时,$exists将匹配包含该字段的文档,包括字段值为null的文档。当$exists为false时,查询将只返回不包含该字段的文档。
需要注意的是,$exists查询不能使用索引。但是,从MongoDB 2.0开始,$exists可以使用索引。
以下是一个使用$exists查询的示例:
db.things.find({ a: { $exists: false } }); // 返回不包含字段a的文档
如果我们想在Mongoid中使用这个查询作为一个scope,可以这样写:
scope :without_recommendation, where: { recommendation: { "$exists" => false } }
这样,我们就可以通过调用`Model.without_recommendation`来获取不包含recommendation字段的文档了。
以上就是解决MongoDB中查找不包含特定字段的项的方法。希望对你有帮助!