MongoDB: & quot; find () & quot; с внешним ключом в другую коллекцию

Извините, если это типичный вопрос «RTM», я новичок в MongoDB и немного читал вручную, но, к сожалению, я не нашел попытки решить эту проблему.

У меня есть две коллекции, одна коллекция — это «статьи», содержащие массив «категорий», в котором есть один или несколько объектов MongoID с идентификаторами моей коллекции категорий.

Я хотел бы отобразить все категории с количеством статей, относящихся к категории. Ниже моего решения я нашел некоторое время исследования:

моя коллекция категорий:

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 категориями это медленно и занимает много времени. Также я не могу сортировать свои категории по количеству статей, не просматривая все статьи.

Есть лучший способ сделать это?

1

Решение

Я не знаком с PHP, поэтому я буду использовать синтаксис mongo. Вы можете использовать конвейер агрегации для вычисления этой серверной стороны за один раз:

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 на статью, хотя. Как часто меняется название категории?

Как правило, вам следует избегать таких операций, как эта, потому что агрегация сканирует каждую статью, распределяет ее по нескольким документам и обрабатывает каждую в соответствующей группе. Лучше инкрементно хранить эту информацию в другой коллекции. Например, вы можете увеличивать счетчик в каждом документе категории каждый раз, когда вставляется статья в этой категории.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]