假设我有两个集合,A和B,A中的单个文档与B中的N个文档相关。例如,模式可能如下所示:
Collection A:
{id: (int),
propA1: (int),
propA2: (boolean)
}
Collection B:
{idA: (int), # id for document in Collection A
propB1: (int),
propB2: (...),
...
propBN: (...)
}
我想从我的API返回属性propB2-BN
和propA2
,并且仅返回信息(例如)propA2 = true
,propB6 = 42
和propB1 = propA1
这通常很简单 - 我查询集合B以查找propB6 = 42
的文档,从结果中收集idA
值,使用这些值查询集合A,并使用集合A过滤结果来自查询的文件。
但是,在保持用户期望的行为的同时,向其添加skip和limit参数似乎是不可能的。天真地将skip和limit应用于第一个查询意味着,由于在查询之后进行过滤,因此可以返回少于限制的文档。更糟糕的是,在某些情况下,当要读取的集合中实际仍有文档时,不能返回任何文档。例如,如果限制为10并且返回的前10个Collection B文档指向集合A中propA2 = false
的文档,则该函数将不返回任何内容。然后用户会认为没有什么可以阅读的,情况可能并非如此。
稍微不那么天真的解决方案是简单地检查返回计数是否为<限制,如果是,请重复查询,直到返回计数=限制。这里的问题是跳过/限制查询,其中用户期望返回的独占文档集实际上可以返回相同的文档。
我想在mongo查询级别应用skip和limit,而不是在API级别,因为查询集合B的结果可能非常大。
MapReduce和aggregation framework似乎只适用于单个集合,因此它们似乎不是替代品。
这似乎是在Mongo使用中出现的很多东西 - 任何想法/提示都会受到赞赏。
答案 0 :(得分:1)
听起来你已经有了解决方案(2)。
您无法在第一次查询时优化/跳过/限制,具体取决于搜索,您可以在第二次查询时执行此操作。
你需要一个循环,就像你写的一样。
我想,.skip对你来说总是很昂贵,因为你需要获得所有结果,然后扔掉它们,模拟跳过,给用户一致的行为。
所有逻辑都必须转到你的循环 - 除非你能以聪明的方式匹配第二个查询(取决于要求)。
出于好奇:如果时间过去了,你现在应该有一个解决方案吗?!