2011-06-21 215 views
2

我有一个名为Events的集合。每个Event文档具有作为嵌入文档的Participants的集合。MongoDB - 查询嵌入文档

现在是我的问题..有没有办法查询Event并得到所有Participants这就是前。年龄> 18?

回答

1

当您在MongoDB中查询集合时,默认情况下它将返回与查询匹配的整个文档。如果需要,您可以对其进行分片并检索单个子文档。

如果你想要的是谁是18岁以上的参与者,它很可能是最好做的两件事情之一:

  1. 商店他们在一个子文档名为“Over18”事件的文档中或者其他的东西。将它们插入到该文档中(如果需要,也可能是其他文档),然后在查询集合时,可以指示数据库仅返回“Over18”子文档。缺点是你将参与者存储在两个不同的子文档中,你必须在插入之前弄清楚他们的年龄。根据您的应用,这可能也可能不可行。如果你需要能够检查任意年龄(即有时18岁,但有时21岁或25岁等),那么这是行不通的。

  2. 查询集合并检索Participants子文档,然后在应用程序代码中对其进行过滤。尽管有些人可能会相信,但这并不可怕,因为你不希望你的数据库一直在做太多的工作。将计算任务卸载到您的应用程序中实际上可以使您的数据库受益,因为它现在可以花费更多的时间查询和更少的时间过滤。它从长远来看导致更好的可扩展性。

+0

感谢您的建议:) - 关于建议2:它会影响我的应用程序的性能,如果它需要过滤掉前。在应用程序中的120.000个文件,相比于在db中进行过滤? – ebb

+0

可能。它真的取决于应用程序,但120k文件很多。我认为你应该对它进行基准测试并看看。如果选项1不可用,选项2不可扩展,则可能需要退后一步,重新考虑文档结构。 –

0

简答:没有。我试图在几个月前做同样的事情,但mongoDB不支持它(至少在版本< = 1.8)。他们的谷歌集团确实已经提出过同样的问题。您可以将参与者作为单独的集合存储,也可以获取整个文档,然后在客户端上对其进行过滤。我知道,远非理想。我仍然试图找出解决这个限制的最佳方法。

+0

不会影响性能,如果我在客户端,而不是数据库过滤它们? – ebb

+0

我认为这取决于您使用的文档数量。 RAM在这里非常重要,mongo将文档保存在内存中,并尝试使用可用的RAM,数量越多,mongo执行的文件系统操作就越少。 无论如何,没有什么可以做的,你想做的事情目前还不支持。 –

0

以供将来参考:这将使用新的聚合框架,MongoDB中2.2可以通过聚合这样的:

db.events.aggregate(
    { $unwind: '$participants' }, 
    { $match: {'age': {$gte: 18}}}, 
    { $project: {participants: 1} 
) 

这将返回N个文档的列表,其中n是多少与会者> 18,其中每个条目看起来是这样的(注意,“参与者”阵场现在拥有一个单一的入口,而不是):

{ 
    _id: objectIdOfTheEvent, 
    participants: { firstName: 'only one', lastName: 'participant'} 
} 

它很可能甚至服务器R ON平坦化编辑参与者名单。有关更多信息,请参阅officcial documentation