NOT IN(SELECT * FROM X)等效于MongoDB

时间:2011-05-04 23:39:21

标签: mongodb

我正在构建一个应用程序,它将定期对MongoDB集合进行脱机匹配。但是,我需要做的是获取之前未匹配的所有潜在匹配的列表。

因此,例如,想象下面的对象(简化以使其更易读):

person { _id: 1, name: 'Matt', previouslyMatched: [2] }

person { _id: 2, name: 'John', previouslyMatched: [1] }

person { _id: 3, name: 'Tony', previouslyMatched: [] }

我想在Matt(id:1)上运行查询,以查明是否有任何其他人员记录不在previousMatched数组中。

现在在SQL中我会像SELECT ID FROM person WHERE ID <> 1 AND ID NOT IN (SELECT match_id from person_match where person_id = 1)那样 当然假设我有一个名为person_match的查找表,其列为person_id,match_id存储所有先前的匹配。我发现这个查询存在潜在的性能缺陷,但请耐心等待,因为这只是一个例子,其他优化工作也将完成。

在MongoDB中,我不知道如何做到这一点。我当然可以检索人员文档(id:1),然后检索所有其他人员文档,并检查ID是否在clientMatched数组客户端,但我担心这对于不必要的大的性能影响数据从数据库服务器传输到客户端。

我知道有一个$nin函数,但是我已经读过这个函数的表现并不好,再一次,我不确定传递一个可能非常长的想法是多么明智随着我的应用扩展,此字段的ID数组。

我的直觉告诉我,答案可能在于Server side code execution,但我不清楚如何实现这一目标。

最后,我还担心实际上可以在单个阵列字段中存储多少项。有实际限制吗?

谢谢, 马特

2 个答案:

答案 0 :(得分:3)

听起来你正试图在这里加入。它不完全是一个连接,但SQL IN语法有效地允许您将一组数据的输出应用于另一组。

在任何一种情况下,MongoDB都不支持连接,它不支持WHERE IN (subtable)语法。您提到的$in语法相当于WHERE IN (a,b,c),具有固定列表。

我在这里看到的唯一方法涉及多个查询(2个或更多)或某种形式的客户端处理。

  

我的直觉告诉我,答案可能在于服务器端代码执行,......

服务器端代码执行在锁定方面有一些限制。如果你想进行大量的查询,我不相信服务器端代码会有效地解决这个问题。

  

最后,我还担心实际上可以在单个阵列字段中存储多少项。有实际限制吗?

MongoDB文档只能包含16MB的数据。这是一个严格的物理限制。

64位整数需要8 bytes。所以这是几百万英镑。字符串显然要少得多。

我个人的经验法则是成千上万或数万(取决于数据)。如果您需要存储“数十万”,您可能会遇到16MB的限制。

答案 1 :(得分:0)

你必须执行多个查询...没有像MongoDB中的Sub-Select或在应用程序端执行一些显式过滤。