2014-09-04 40 views
0

我有一个带有子分区的模式。仅返回与Mongo汇总匹配的子分区

// Schema 
var company = { 
    _id: ObjectId, 
    publish: Boolean, 
    divisions: { 
    employees: [ObjectId] 
    } 
}; 

我需要找到与我的查询匹配的所有subdocs(部门)。看起来我必须使用2个匹配项 - 一个筛选出最初的文档,另一个筛选出从所得的$ unwind操作中匹配的子目录。有没有更高效的方法?我发现这个ticket,但我不确定这是做我需要的。

回答

0

做这两场比赛是正确的。您可以消除第一个匹配阶段,只是放松一下,但是通过初始$匹配,您可以将管道缩小到准确生成至少一个输出文档的文档(即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),“出版”:真})

,这将是比聚集更快(不说,聚合会很慢;这只是相对较快)。我不会告诉你这样做 - 使用你自己的用例知识来做出正确的呼叫。

+0

谢谢 - 我不聚集,因为我的真实代码要复杂得多。所以你建议的最有效的方法是在两个匹配中维护'division.employee'查询,只需添加一个索引?我不确定我是否应该只在第二个或第二个中拥有'division.employee'。 – cyberwombat 2014-09-05 03:00:48

+0

我认为这两者都是最好的。第一个$匹配是您使用索引并使下一步处理尽可能少的文档的机会,而第二个$匹配则需要条件才能获得正确的结果。 – wdberkeley 2014-09-05 14:33:02