我正在开发一个具有产品目录和n级类别树的应用程序.
Category 1
--Category 1.1
----Category 1.1.1
------Product 1.1.1.1
------Product 1.1.1.2
----Product 1.1.1
--Category 1.2
----Product 1.2.1
--Product 1.1
我需要类似平面数组的内容:
Category 1
Category 1.1
Category 1.1.1
Product 1.1.1.1
Product 1.1.1.2
Product 1.1.1
Category 1.2
Product 1.2.1
Product 1.1
但是问题是我需要太多查询和太多时间来生成此查询(我或多或少有700个产品和200个类别,执行它们大约需要846个查询和2100毫秒).我可以添加更多的联接,但是执行时间会大大增加.我正在与可翻译实体合作.
有什么想法可以最小化查询数量和执行时间?类别具有自我关系并与产品有关系.
我认为一种选择可以是获取所有类别并创建有序树,然后再次重做平面数组,但是我不知道这是否是最佳选择…
预先感谢您的任何帮助!
public function generateCategoriesTree($categories, $result = array()) {
$tempResult = array();
if(count($categories)) {
foreach($categories as $k => $v) {
$tempResult[] = $v;
if(count($v->getCategories())) {
$temp = $this->generateCategoriesTree($v->getCategories(), $result);
foreach($temp as $kk => $vv) {
$tempResult[] = $vv;
}
}
}
}
return array_merge($result, $tempResult);
}
但是问题不在这里,问题在于当我尝试访问树的第二层时,当调用方法getcategories时,该方法在数据库中执行查询.
更新
使用此解决方案,我将查询数量从700减少到100,并将执行时间从2100ms减少到350ms.我认为现在就足够了,因为此操作每小时使用几次.
if ($this->isGranted('ROLE_EMPLOYEE') || $currentUser->isXXXXXXSeller()) {
$XXXXXXCategories = $em->getRepository('CatalogBundle:Category')->getMainCategoriesByBrand(1);
if(is_array($XXXXXXCategories)) {
$categoriesXXXXXX = $this->get('core_tools')->generateCategoriesTree($XXXXXXCategories);
$categories = new ArrayCollection(
array_merge($categories->toArray(), $categoriesXXXXXX)
);
}
}
$categoriesToShow = array();
$products = $em->getRepository('CatalogBundle:Product')->getAllOrderedByPosition();
if(is_array($products) && is_array($categories)) {
foreach($categories as $category) {
$categoriesToShow["c_".$category->getId()] = array(
"category" => $category,
"products" => array(),
);
}
foreach($products as $product) {
if($product->getCategories()) {
foreach($product->getCategories() as $productCategory) {
if(array_key_exists("c_".$productCategory->getCategory()->getId(), $categoriesToShow)) {
$categoriesToShow["c_".$productCategory->getCategory()->getId()]['products'][] = $product;
}
}
}
}
}
解决方法:
如果目录不是很频繁地更改(即:每隔几秒钟就更改一次),则只需进行一次艰苦的工作,然后将输出缓存起来,以便立即使用.
目录更改时-重建缓存.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。