2014-08-28 113 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}}) }