在我的应用中,我有查询:
Model.where(flagged: true, saved: false)
或者我可以使用Model.all(:conditions => {flagged: true, saved: false})
一切都很好。
现在我如何得到该查询的否定?即所有不满足flagged: true
和saved: false
的模型实例(相当于flagged != true
或saved != false
)
Model.excludes(flagged: true, saved: false)
返回满足flagged != true
和saved != false
)的实例
答案 0 :(得分:1)
您需要下载到MongoDB ruby驱动程序才能执行此操作。
如果我正确理解了这个问题,当你在$ ne子句中寻找OR时,Mongoid的exclude命令会执行AND,并且没有方法。
这就是你想要的shell:
find({$or: [{flagged: {$ne: true}}, {saved: {$ne: true}}]})
在ruby中,该查询如下所示:
query = {"$or" => [{"flagged" => {"$ne" => true}}, {"saved" => {"$ne" => true}}]}
如果我没记错,你可以说:
Model.collection.find(query)
其中查询是我在上面定义的文档,它应该可以工作。
答案 1 :(得分:0)
您是否尝试过$nor
运营商?
Model.all(:conditions => { '$nor' => [ { flagged: true }, { saved: false } ]})
更多信息:http://docs.mongodb.org/manual/reference/operator/query/nor/
答案 2 :(得分:-1)
对于您在问题中使用的特定情况,您可以执行以下操作:
Model.any_of({ flagged: false, saved: true }, { flagged: true, saved: true }, { flagged: false, saved: false } )
但是,正如您在评论中所说,您实际上正在寻找一般解决方案。 AFAIK在Mongoid或MongoDB中无法做到这一点。
原因很可能在于您无法在MongoDB查询中进行连接。例如,用于取消查询的传统SQL方法可能是:
SELECT * FROM mytable t
WHERE t.id NOT IN ( SELECT t2.id FROM mytable t2 WHERE t2.condition = true )
或者,避免N + 1选择问题
SELECT t.*, t2.id FROM mytable t
OUTER JOIN mytable t2 ON ( t1.id AND t2.condition = true )
WHERE t2.id = NULL
两者都依赖于以某种方式加入两个选择,在Mongo你不能这样做。
唯一的另一种方法是以某种方式反转逻辑,以便得到您特定示例的上述答案。我认为让Mongo自动执行此操作是一个非常糟糕的主意,因为最终会产生代码生成任意复杂的查询,而这些查询无法控制,也无法进行优化。
答案 3 :(得分:-2)
我发现我可以使用Javascript expression syntax
执行此操作所以否定Model.where(flagged: true, saved: false)
- 可以表示为Model.where("this.flagged == true && this.saved == false")
是
Model.where("!(this.flagged == true && this.saved == false)")
正如Russell的评论所说,这比使用原生查询语言效率低,但对于我的目的来说这不是问题所以我现在正确认为这是正确的 - 但是对于未来的读者请记住性能影响。
如果某人可以给出仅使用本机查询语言的答案,而不进行明确的布尔逻辑扩展,我会将其标记为正确(也许这可能在未来版本的Mongodb / Mongoid中 - 如果可以的话)现在就完成了。)