2012-05-23 47 views
4

所以在這裏引用的所有文件的問題是:MongoDB的 - 我如何才能找到不是由文件從另一個集合

我在集合的有文件,當第一次創建它,它不被任何引用其他文件。在某一時刻,集合B中的文檔將被創建,它將引用集合A中文檔的ObjectId。

什麼是集合A中沒有被I文檔引用的所有文檔的最佳方式? ?

我知道MongoDB不支持連接,但我想知道除了從集合B獲取所有引用的ObjectId並找到不在該列表中的集合A中的文檔之外,是否有解決此問題的解決方案,因爲此解決方案可能不會很好地擴展。

我可以將集合A中的文檔嵌入到集合B的文檔中,然後將其從集合A中刪除嗎?這是最好的解決方案嗎?

感謝您的幫助和評論。

回答

4

很多的選擇:

1)B文件的ID添加到在一個數組一份文件(反向參考)。現在您可以查找在該數組中沒有任何元素的文檔。問題:如果您有大量交叉引用,則數組可能會因文檔大小而變得過大。

2)添加追蹤A和B之間引用的集合C.行爲就像一個連接表。

3)在'引用'中有一個簡單的標誌。當您添加一個B標記時,它引用的所有A都是「引用的」。當你刪除B時,對B所引用的所有A進行B掃描,並取消標記不再有引用的A。問題:可能不同步。

4)在B上使用map reduce來創建一個包含任何B引用的所有A的ID的集合。使用該集合來標記所有引用的A(首先將它們全部取消標記之後)。可以使用它來定期修復(3)。

5)將兩個文檔類型放在同一個集合中,並使用map reduce來發出_id和一個標記,以表示'在A中'或'由B引用'。在減少步驟中查找具有「在A中」但不是「由B引用」的任何組。

...

+0

謝謝,我想我會用選項1先走,因爲我需要的所有文件B在文件A相關的次歷史......我也可能設置一個標誌,如果當指示文件B目前適用。 –

2

由於沒有聯接,因此只有您提到的選項是:使用嵌入式文檔或使用兩部分查詢。

這取決於您的實施,但將文檔類型B添加到A中的相應文檔聽起來像是最好的選擇。這樣,你可以用一個簡單的查詢($exists operator)檢索A公司沒有A B ...

A.find({ B: { $exists: false } }) 
2

用MongoDB的3.2,添加$lookup運營商使這成爲可能:

db.a.aggregate(
[ 
    { 
     $lookup: { 
      from: "b", <-- secondary collection name containing references to _id of 'a' 
      localField: "_id", <-- the _id field of the 'a' collection 
      foreignField: "a_id", <-- the referencing field of the 'b' collection 
      as: "references" 
     } 
    }, 
    { 
     $match: { 
      references: [] 
     } 
    } 
]); 

上面的查詢將返回集合a那些在收集b沒有引用的所有文檔。

不過要小心。性能可能成爲大型集合的一個問題。


相關問題