2015-02-23 88 views
0

對不起,如果這可能是一個典型的「RTM」 - 問題,我是新來的MongoDB,並做了一些手動閱讀,但很遺憾,我沒有找到一個嘗試解決這個問題。MongoDB:「查找()」與外鍵到不同的集合

我有兩個集合,一個集合是「articles」,其中包含一個「categories」數組,其中包含一個或多個MongoID對象,其ID爲我的類別集合。

我想顯示所有類別與指向該類別的文章數量。下面我的解決辦法,我發現atfer研發的一段時間:

我收藏的類別:

Array 
(
    [_id] => MongoId Object 
     (
      [$id] => 54eb1510974f5590179702aa 
     ) 

    [name] => Test 
    [multiplier] => 2  
) 

我的文章收集:

Array 
(
    [_id] => MongoId Object 
     (
      [$id] => 54e5e39f974f5535248b4bdf 
     ) 

    [productnumber] => 63483 

    [categories] => Array 
     (
      //... other categories... 
      [1] => MongoId Object 
       (
        [$id] => 54eb1510974f5590179702aa 
       ) 

     ) 
    [image] => /var/www/mongodbtest/Files/FTP/images/63483.jpg 
) 

我當前的PHP代碼:

foreach($oAllCategories as $oCategory) 
{    
    $iArticleCount = $oArticles->find(array('categories' => $oCategory['_id']))->count(); 
    // Debug 
    echo $oCategory['name'].' = '.$iArticleCount.' <br />'; 
} 

現在的問題是,有70'000篇文章和2'200類別,這是緩慢的,需要很多的時間。此外,我無法按照文章數量對我的分類進行分類,也無法遍歷所有文章。

有沒有更好的方法來做到這一點?

回答

2

我對PHP不熟悉,所以我將使用mongo shell語法。您可以使用聚合管道來計算這個服務器端一氣呵成:

db.articles.aggregate([ 
    { "$unwind" : "$categories" }, 
    { "$group" : { "_id" : "$categories", "count" : { "$sum" : 1 } } } 
]) 

$unwind階段「開卷」每篇文章文檔沿其categories陣列,例如

{ "x" : 1, "categories" : ["a", "b", "c"] } 
===> 
{ "x" : 1, "categories" : "a" }, 
{ "x" : 1, "categories" : "b" }, 
{ "x" : 1, "categories" : "c" } 

然後$group階段合併沿categories值的所有文件,並計入該組中元素的個數。結果看起來像

{ "_id" : "c", "count" : 1 } 
{ "_id" : "b", "count" : 1 } 
{ "_id" : "a", "count" : 1 } 

_id的是類_id的,你可以與categories集合連接變成名。不過,我認爲你應該只在文章中保存類別名稱_id。類別名稱實際更改的頻率如何?

但是,通常情況下,您應該避免進行這樣的操作,因爲聚合正在掃描每篇文章,將其展開爲多個文檔,並將每個文檔處理爲相應的組。最好在另一個集合中增量維護此信息例如,每次插入該類別的文章時,您都可以在每個類別文檔中增加一個計數。

+0

非常感謝。即使這不是真正「我想聽到的」,它似乎是唯一正確的信息,因爲JOIN可以解決問題,但它們不在MongoDB中。我會用你的建議來實施一個計數器。感謝您的時間和信息。 – 2015-02-25 09:25:45