使用$ project的结果会超出最大文档大小

时间:2017-07-20 14:24:01

标签: mongodb pymongo

我有2个收藏品,比如说A和B.

示例A:

[
    {"Account": "99", "Cat_1": "Losses",  "Cat_2": "Marketing"},
    {"Account": "89", "Cat_1": "Losses",  "Cat_2": "Consultancy"},
    {"Account": "79", "Cat_1": "Losses",  "Cat_2": "Marketing"},
    {"Account": "69", "Cat_1": "Losses",  "Cat_2": "Consultancy"},
    {"Account": "59", "Cat_1": "Profits", "Cat_2": "Marketing"},
    {"Account": "49", "Cat_1": "Profits", "Cat_2": "Consultancy"},
    {"Account": "29", "Cat_1": "Profits", "Cat_2": "Marketing"},
    {"Account": "00", "Cat_1": "Profits", "Cat_2": "Consultancy"}
...
]

例B:

[
    {"Name": "Example A", "Year": 2014, "Account": "99", "Amount": -5000},
    {"Name": "Example A", "Year": 2015, "Account": "99", "Amount": -5000},
    {"Name": "Example A", "Year": 2014, "Account": "89", "Amount": -2000},
    {"Name": "Example A", "Year": 2015, "Account": "79", "Amount": -3000},
    {"Name": "Example A", "Year": 2014, "Account": "69", "Amount": 0},
    {"Name": "Example A", "Year": 2015, "Account": "59", "Amount": 100},
    {"Name": "Example A", "Year": 2016, "Account": "49", "Amount": 5000},
    {"Name": "Example A", "Year": 2014, "Account": "29", "Amount": 4000},
    {"Name": "Example A", "Year": 2015, "Account": "00", "Amount": 900},
    {"Name": "Example B", "Year": 2013, "Account": "99", "Amount": -500},
    {"Name": "Example B", "Year": 2011, "Account": "89", "Amount": -10000},
    ...
]

现在,我想要获取所有类型的“Cat_1”帐户以结束此操作:

[
    {"cat": "Losses",  "Accounts": ["99", "89", "79", "69"]},
    {"cat": "Profits", "Accounts": ["59", "49", "29", "00"]}
]

或者,我会为某个类别获取Cat_n并获得同样的结果。

接下来,我展开帐户并对集合B执行查找。这是出错的地方,并且超出了最大文档大小。我应该提一下,我一次只对1个实用程序感兴趣,所以我的查询现在看起来像这样:

...
{
  "$lookup": {
    "from": "collection_B",
    "localField": "Account",
    "foreignField": "Account",
    "as": "results"
  }
},
{
  "$addFields": {
    "results": {
      "$filter": {
        "input": "$results",
        "as": "comp",
        "cond": {
          "$eq": [
            "$$results.Name", "Example A"
          ]
        }
      }
    }
  }
},
...

在查找之后,我使用$addFields来覆盖原始结果字段,因为我不想要它们中的大多数,因为我只对特定的使用者感兴趣。

第二个集合中有大约1000万个文档,每个使用者大约300k。因此,在此查找之后,结果中永远不会超过300k。在请求cat_1类别时,结果将是两个数组“损失”和“利润”,它们都包含大约800个帐户。

我使用$project缩小文档大小,只包含我真正想要的字段。此外,我还尽早使用$match来消除聚合中不需要的文档。

虽然这一切都没有帮助,但该文件仍然超出了16MB的BSON限制。只有当$limit使用相当低的±300值时,才会返回结果并且缺少信息。

我最感兴趣的是为给定的使用者和Cat_n

生成包含类似内容的文档
{
  "Name": "Example A",
  "Losses": [
    {"Year": 2014, "Amount": ...},
    {"Year": 2015, "Amount": ...},
    {"Year": 2016, "Amount": ...}
  ],
  "Profits": [
    {"Year": 2014, "Amount": ...},
    {"Year": 2015, "Amount": ...},
    {"Year": 2016, "Amount": ...}
  ],
}

我一直在考虑创建两个单独的聚合,一个用于获取类别,一个用于聚合来自集合B的结果。但是我必须检查每个文档以找出它属于哪个类别,哪个不是看起来效率非常高。 或者,我可以创建第三个集合,在那里我合并来自两个集合的文档并在那里进行聚合,但是如果可能的话我宁愿避免这种情况,因为它会在以后维护或查看这些数据时增加额外的复杂性。

1 个答案:

答案 0 :(得分:-1)

我发现$ lookup返回的匹配数组超过了16MB的BSON限制。因此,无法以任何方式检索结果。

管理通过反转逻辑来解决它,我现在正在从A中的集合B执行查找。这实际上更有意义,因为我现在可以在执行查找之前过滤掉94%的文档,而不是在这之后做到这一点。