2017-06-07 96 views
0

我在PyMongo中使用$ lookup来成功“加入”两个集合(这是可行的)。我遇到问题,即我加入的第二个集合在返回所有记录时可能会超过BSON文档大小。MongoDB聚集限制查找

我期待使用$极限限制所允许“match_docs”,例如下加入记录数:从“意见” 100的最大记录每obj_id:

db.indicators.aggregate([ 
    { 
    "$lookup": { 
     "from": "comments", 
     "localField": "_id", 
     "foreignField": "obj_id", 
     "as": "match_docs" 
    } 
    } 
]) 

我已经试过各种$限制的类型,它似乎只限制整体结果的总数,而不仅仅是加入。

+0

你可以不设置在$查找的限制,但你并不需要这使查询工作。将'{allowDiskUse:true}'添加到您的聚合选项应该可以解决问题 – felix

+0

@felix OP正在讨论BSON文档大小限制,而不是内存限制。 –

+1

为了减少结果,您可以''匹配'从'$ lookup'返回的内容吗?当流水线阶段是'$ lookup' - >'$ unwind' - >'$ match'并且'$ match'(相继)和'$ match'中的条件引用了$ lookup',后两个阶段被“提升”到'$ lookup'中。这是一个优化,以减少可能的条目返回。 –

回答

1

如果你做一个$unwind紧跟在$lookup,管道将得到优化,基本上结合了两个阶段帮助绕过16MB的限制,可能会导致从$lookup返回大量的文件。

请记住,如果外部收集中的单个文档加上本地集合中文档的大小超过16 MB,则此优化无法提供帮助。

+0

还要注意,如果'$ unwind'之后跟着'$ match',它处理外部集合,那么查询条件也会与'$ unwind'一起被“悬挂”到'$ lookup'中。你可以使用'{“explain”:true}'作为参数来看这个聚合。 –

+0

@NeilLunn这里有一些注意事项:https://jira.mongodb.org/browse/SERVER-21612。此外,要为随后的“$ match”使用索引,您需要有一个以'$ lookup'使用的字段开头的复合索引,后面跟着'$ match'中的字段。 –

+0

索引与我在这里说的无关,这是一个单独的问题。您在这里所做的两个回复看起来好像是由某人在Google中搜索条件完成的,并且可以通过示例来阐明整个故事。 –

1

我能弄明白。

$查找 - > $匹配 - > $项目

db.indicators.aggregate([{ 
    "$lookup": { 
     "from": "comments" 
     , "localField": "_id" 
     , "foreignField": "obj_id" 
     , "as": "match_docs" 
    } 
}, { 
    "$match": { 
     "match_docs": { 
      "$exists": True 
     } 
    } 
}, { 
    "$project": { 
     "match_docs_agg": { 
      "$slice": ["$match_docs", 3] 
     } 
    } 
}]) 
+1

讨厌你的泡泡,但实际上并没有做任何事情来避免BSON限制被打破。它也是一个“给定”来测试数组字段的存在,因为它在“$ lookup”的输出中始终是“创建的”。“$切片”只会在“已经拉入文档之后减小结果的大小”,所以BSON限制仍然可以被破坏。这对你来说唯一的理由是因为拉入的文件实际上并没有打破这个限制。无论如何,16MB是相当多的 –

+0

你100%正确,它只是在返回“3”的意义上做了我想要的,但它仍然在流水线中断。 – gleb1783

+0

您可以改为在您的问题中显示您打算进行的聚合。根据你的“意图”,我的意思是'$ lookup'操作,以及你想要对接下来的信息进行的聚合操作,即使它只是一个'$ slice'。然后,我可以真正展示你要做什么。 –