做这两场比赛是正确的。您可以消除第一个匹配阶段,只是放松一下,但是通过初始$匹配,您可以将管道缩小到准确生成至少一个输出文档的文档(即publish : true
和某些employees
ObjectId与给定文档匹配的那些文档的ObjectId)。您将能够使用索引(如{ publish : 1, divisions.employees : 1 }
上的索引)快速执行第一个匹配阶段。
但是,您应该问自己,为什么您在这里使用聚合管道,以及是否合适。您是否通常会查询属于publish : 1
公司的特定员工?这是您的用例的主要查询之一吗?如果它不频繁或不重要,那么聚合是一个很好的方法。否则,你应该重新考虑模式。你可以把这个查询易于使用的模式类似
{
"_id" : ObjectId,
"publish" : Boolean,
"company" : (unique identifier, possibly a String or ObjectId)
}
该车型员工文档和denormalizes公司信息到员工的文档。然后将查询一样简单
db.employees.find({“_id”:物件(用户ID),“出版”:真})
,这将是比聚集更快(不说,聚合会很慢;这只是相对较快)。我不会告诉你这样做 - 使用你自己的用例知识来做出正确的呼叫。
谢谢 - 我不聚集,因为我的真实代码要复杂得多。所以你建议的最有效的方法是在两个匹配中维护'division.employee'查询,只需添加一个索引?我不确定我是否应该只在第二个或第二个中拥有'division.employee'。 – cyberwombat 2014-09-05 03:00:48
我认为这两者都是最好的。第一个$匹配是您使用索引并使下一步处理尽可能少的文档的机会,而第二个$匹配则需要条件才能获得正确的结果。 – wdberkeley 2014-09-05 14:33:02