2014-08-28 75 views

回答

7

我更好的方法是使用MongoDB的本地语法,而不是像方法或JavaScript评估那样使用rails,就像您链接到的问题的接受答案中指出的那样。特别是评估JavaScript条件会慢得多。

$exists与一些长度大于零的一个阵列中的逻辑延伸是使用"dot notation"和测试为“零指数”或第一元件的阵列的存在:

Customer.collection.find({ "orders.0" => { "$exists" => true } }) 

,可以看起来可以用任何索引值完成,其中n-1等于最小测试数组“长度”的索引值。

值得关注的是用于“零长度”阵列排斥$size操作者也是一个有效的替代方案,用$not当用于否定匹配:

Customer.collection.find({ "orders" => { "$not" => { "$size" => 0 } } }) 

但这并不完全适用于较大的“尺寸“测试,你就需要指定所有尺寸要排除:

Customer.collection.find({ 
    "$and" => [ 
     { "orders" => { "$not" => { "$size" => 4 } } }, 
     { "orders" => { "$not" => { "$size" => 3 } } }, 
     { "orders" => { "$not" => { "$size" => 2 } } }, 
     { "orders" => { "$not" => { "$size" => 1 } } }, 
     { "orders" => { "$not" => { "$size" => 0 } } } 
    ] 
}) 

所以其他的语法更加清晰:

Customer.collection.find({ "orders.4" => { "$exists" => true } }) 

这意味着5个或更多成员以简洁的方式。

请注意,单单这些条件都不能只是一个索引,所以如果你有另一个过滤点,最好先包含这个条件。

+0

这不很好地工作,你的建议,我会使用本地MongoDB的语法,谢谢! – jsurf 2014-08-28 00:52:13

5

只是增加我的解决方案,这可能是有人帮助:

scope :with_orders, -> { where(orders: {"$exists" => true}, :orders.not => {"$size" => 0}}) }