Mongoid:基于嵌入式文件阵列

问题描述:

的大小查询这类似于这样的问题在这里,但我无法弄清楚如何将其转换为Mongoid语法:Mongoid:基于嵌入式文件阵列

MongoDB query based on count of embedded document

比方说,我有Customer: {_id: ..., orders: [...]}

我希望能够找到所有有现有订单的客户,即order.size> 0.我试过像Customer.where(:orders.size.gt => 0)这样的查询无济于事。可以用exists?运营商完成吗?

我更好的方法是使用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

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

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