【发布时间】:2018-05-31 05:14:05
【问题描述】:
我正在尝试选择隐私设置与提供的文档相匹配的任何文档以及任何没有任何隐私设置(即公开)的文档。
当前的行为是,如果我有一个包含一组对象 ID 的架构,该数组引用了另一个集合:
privacy: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Category',
index: true,
required: true,
default: []
}],
我想过滤我的类别和公共类别的所有内容,在我们的例子中是没有隐私设置的内容。即一个空数组 []
我们目前使用 or 查询
{"$or":[
{"privacy": {"$size": 0}},
{"privacy": {"$in":
["5745bdd4b896d4f4367558b4","5745bd9bb896d4f4367558b2"]}
}
]}
我很想通过仅提供一个空数组 [] 作为 $in 语句中的比较选项之一来查询它。这在 mongodb 中是可能的:
db.emptyarray.insert({a:1})
db.emptyarray.insert({a:2, b:null})
db.emptyarray.insert({a:2, b:[]})
db.emptyarray.insert({a:3, b:["perm1"]})
db.emptyarray.insert({a:3, b:["perm1", "perm2"]})
db.emptyarray.insert({a:3, b:["perm1", "perm2", []]})
> db.emptyarray.find({b:[]})
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
> db.emptyarray.find({b:{$in:[]}})
> db.emptyarray.find({b:{$in:[[], "perm1"]}})
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce1"), "a" : 3, "b" : [ "perm1" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce2"), "a" : 3, "b" : [ "perm1", "perm2" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
> db.emptyarray.find({b:{$in:[[], "perm1", null]}})
{ "_id" : ObjectId("5a305f3dd89e8a887e629cde"), "a" : 1 }
{ "_id" : ObjectId("5a305f3dd89e8a887e629cdf"), "a" : 2, "b" : null }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce1"), "a" : 3, "b" : [ "perm1" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce2"), "a" : 3, "b" : [ "perm1", "perm2" ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
> db.emptyarray.find({b:{$in:[[]]}})
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce0"), "a" : 2, "b" : [ ] }
{ "_id" : ObjectId("5a305f3dd89e8a887e629ce3"), "a" : 3, "b" : [ "perm1", "perm2", [ ] ] }
可能是这样的:
"privacy_locations":{
"$in": ["5745bdd4b896d4f4367558b4","5745bd9bb896d4f4367558b2",[]]
}
但是这个查询可以在控制台 (CLI) 中工作,但不能在引发转换错误的代码中工作:
{
"message":"Error in retrieving records from db.",
"error":
{
"message":"Cast to ObjectId failed for value \"[]\" at ...
}
}
现在我完全理解演员阵容正在发生,因为 Schema 被定义为 ObjectId。
但我仍然发现这种方法缺少两种可能的情况。
我相信可以在 $in 语句中查询(在 MongoDB 中)空选项或空数组。
array: {$in:[null, [], [option-1, option-2]}
这对吗?
我一直在想,解决我的问题(无法在选项中选择或为空)的最佳解决方案可能是让空数组成为具有 ALL 修复选项的数组。隐私设置意味着全部,而不是现在的状态,如果未设置,则视为全部。
但我不想对现有代码进行重大重构,我只需要看看我是否可以做出更好的查询或更高性能的查询。
今天我们的查询使用了一个索引有问题的 $OR 语句。即使它很快,我也想引起人们对这个问题的关注,即使它不被认为是一个错误。
我将不胜感激任何 cmets 或指导。
【问题讨论】:
标签: mongodb mongoose mongodb-query mongoose-schema