下面的测试展示了如何通过 MongoDB 聚合框架做你想做的事。
但是,如果选择使用它,请仔细测试其性能。
为了获得更高的缩放性能,您应该考虑添加一个显式字段,例如
team_participants_count 跟踪 team_participants 的数组大小,
并且该显式字段可以在正常查询中使用。
如果您尝试其他解决方案,例如其他 cmets 中引用的 '$where',
你也应该仔细衡量他们的表现。
享受吧!
test/unit/scorecard_test.rb
require 'test_helper'
require 'pp'
class ScorecardTest < ActiveSupport::TestCase
def setup
Scorecard.delete_all
end
test "select by array size comparison" do
docs = [
{team_participants:[{name:'a'}]},
{team_participants:[{name:'b'},{name:'c'}]},
{team_participants:[{name:'d'},{name:'e'},{name:'f'}]},
{team_participants:[{name:'g'},{name:'h'},{name:'i'},{name:'j'}]}
]
Scorecard.create(docs)
assert_equal(4, Scorecard.count)
pp Scorecard.collection.aggregate(
[{'$unwind' => '$team_participants'},
{'$group' => {'_id' => '$_id',
'team_participants' => {'$push' => '$team_participants'},
'team_participants_count' => {'$sum' => 1},
'created_at' => {'$first' => '$created_at'},
'updated_at' => {'$first' => '$updated_at'}}},
{'$match' => {'team_participants_count' => {'$gte' => 3}}}
])
end
end
$ rake 测试
Run options:
# Running tests:
[1/1] ScorecardTest#test_select_by_array_size_comparison[{"_id"=>"535b1a90a3f576ea5100000a",
"team_participants"=>
[{"_id"=>"535b1a90a3f576ea5100000b", "name"=>"g"},
{"_id"=>"535b1a90a3f576ea5100000c", "name"=>"h"},
{"_id"=>"535b1a90a3f576ea5100000d", "name"=>"i"},
{"_id"=>"535b1a90a3f576ea5100000e", "name"=>"j"}],
"team_participants_count"=>4,
"created_at"=>2014-04-26 02:31:44 UTC,
"updated_at"=>2014-04-26 02:31:44 UTC},
{"_id"=>"535b1a90a3f576ea51000006",
"team_participants"=>
[{"_id"=>"535b1a90a3f576ea51000007", "name"=>"d"},
{"_id"=>"535b1a90a3f576ea51000008", "name"=>"e"},
{"_id"=>"535b1a90a3f576ea51000009", "name"=>"f"}],
"team_participants_count"=>3,
"created_at"=>2014-04-26 02:31:44 UTC,
"updated_at"=>2014-04-26 02:31:44 UTC}]
Finished tests in 0.031745s, 31.5010 tests/s, 31.5010 assertions/s.
1 tests, 1 assertions, 0 failures, 0 errors, 0 skips