2017-07-20 54 views
0

我有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個utiliser感興趣,所以我的查詢看起來像這樣的時刻:

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

我用$addFields覆蓋原來的結果領域的查找後,因爲其中大部分人我不想要,因爲我只對特定的用戶感興趣。

第二個集合中有大約10M個文檔,每個utiliser約爲300k。所以在查找之後,結果中不會超過300k。當請求cat_1類別時,結果將是兩個陣列「損失」和「利潤」,它們都包含大約800個賬戶。

我減小文檔大小$project只包含我實際需要的字段。此外,我還儘可能早地使用$match以消除聚合中不需要的文檔。

雖然這一切都沒有幫助,但該文檔不斷超出16MB BSON限制。只有使用$limit時,如果值爲±300,結果將被返回並且缺少信息。

什麼我中生成包含這樣的事情對於一個給定utiliser和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": ...} 
    ], 
} 

我一直在爲獲得該類別想着剛剛創建了兩個單獨的聚合,一個的文件,最終有興趣1個用於彙總來自B集合的結果。但是,我必須檢查每個文檔以找出它屬於哪個類別,這看起來效率不高。 或者,我可以創建第三個集合,將兩個集合中的文檔合併到一起,然後在那裏進行集合,但如果可能,我寧願避免這樣做,因爲這會在稍後維護或審閱此數據時增加額外的複雜性。

+1

您是否期待這樣「2.6版本中已更改:db.collection.aggregate()方法返回一個遊標並可返回任意大小的結果集。以前的版本將所有結果都返回到單個文檔中,結果集的大小限制爲16兆字節「https://docs.mongodb.com/manual/reference/method/db.collection.aggregate/ –

+0

@DanieleTassone,有趣的功能!雖然它現在沒有解決我的問題,但我有一種感覺,我可能會在某處使用它 – kbao

回答

-1

我發現$ lookup返回的匹配數組超出了16MB的BSON限制。因此,無法以任何方式檢索結果。

被管理通過顛倒邏輯來解決它,現在我正在A中從集合B執行查找。這實際上讓我更有意義,因爲我現在可以在執行查找之前過濾掉94%的文檔,而不是之後必須這樣做。

+1

聽起來更像是一種「解決方法」而不是解決方案。正確的做法是實際上「$ unwind」和'$ match'直接跟在'$ lookup'之後,原因是這兩個流水線階段實際上成爲'$ lookup'階段的一部分,結果是你只能得到你的條件要求的數據,並且因爲它的「解繞」你不可能打破16MB的限制,你需要看看「explain」輸出來看管道上的實際效果,我在https://stackoverflow.com/a/44960412/2313887上給出了更多的細節。你可以用相反的方法做同樣的事情。 –