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个或更多成员以简洁的方式。
请注意,单单这些条件都不能只是一个索引,所以如果你有另一个过滤点,最好先包含这个条件。
答
只是增加我的解决方案,这可能是有人帮助:
scope :with_orders, -> { where(orders: {"$exists" => true}, :orders.not => {"$size" => 0}}) }
这不很好地工作,你的建议,我会使用本地MongoDB的语法,谢谢! – jsurf 2014-08-28 00:52:13