Просмотр исходного кода

perf(core): Fix slow queries when entities have self-referencing relations (#4020)

gabriellbui 1 месяц назад
Родитель
Сommit
ae93c9fe3d
1 измененных файлов с 21 добавлено и 13 удалено
  1. 21 13
      packages/core/src/service/helpers/utils/tree-relations-qb-joiner.ts

+ 21 - 13
packages/core/src/service/helpers/utils/tree-relations-qb-joiner.ts

@@ -7,8 +7,7 @@ import { VendureEntity } from '../../../entity';
 
 /**
  * @description
- * Check if the current entity has one or more self-referencing relations
- * to determine if it is a tree type or has tree relations.
+ * Check if the current entity uses TypeORM tree decorators (@Tree, @TreeParent, @TreeChildren).
  * @param metadata
  * @private
  */
@@ -21,9 +20,6 @@ function isTreeEntityMetadata(metadata: EntityMetadata): boolean {
         if (relation.isTreeParent || relation.isTreeChildren) {
             return true;
         }
-        if (relation.inverseEntityMetadata === metadata) {
-            return true;
-        }
     }
     return false;
 }
@@ -81,11 +77,6 @@ export function joinTreeRelationsDynamically<T extends VendureEntity>(
             return;
         }
         parentPath = parentPath?.filter(p => p !== '');
-        const currentMetadataIsTree =
-            isTreeEntityMetadata(currentMetadata) || sourceMetadataIsTree || parentMetadataIsTree;
-        if (!currentMetadataIsTree) {
-            return;
-        }
 
         const parts = currentPath.split('.');
         let part = parts.shift();
@@ -104,6 +95,18 @@ export function joinTreeRelationsDynamically<T extends VendureEntity>(
             return;
         }
 
+        const currentMetadataIsTree =
+            isTreeEntityMetadata(currentMetadata) || sourceMetadataIsTree || parentMetadataIsTree;
+
+        const relationIsSelfReferencing = relationMetadata.inverseEntityMetadata === currentMetadata;
+
+        // Only proceed with manual joining if:
+        // 1. We're in a tree entity context (using @Tree, @TreeParent, @TreeChildren), OR
+        // 2. This specific relation is self-referencing (either the relation is self-referencing or the relation is a custom field relation)
+        if (!currentMetadataIsTree && !relationIsSelfReferencing) {
+            return;
+        }
+
         let joinConnector = '_';
         if (relationMetadata.isEager) {
             joinConnector = '__';
@@ -123,18 +126,23 @@ export function joinTreeRelationsDynamically<T extends VendureEntity>(
 
         const inverseEntityMetadataIsTree = isTreeEntityMetadata(relationMetadata.inverseEntityMetadata);
 
-        if (!currentMetadataIsTree && !inverseEntityMetadataIsTree) {
+        const shouldProcessSubRelations =
+            currentMetadataIsTree || inverseEntityMetadataIsTree || relationIsSelfReferencing;
+
+        if (!shouldProcessSubRelations) {
             return;
         }
 
         const newEagerDepth = relationMetadata.isEager ? eagerDepth + 1 : eagerDepth;
 
+        const propagatedTreeContext = currentMetadataIsTree || relationIsSelfReferencing;
+
         if (newEagerDepth <= maxEagerDepth) {
             relationMetadata.inverseEntityMetadata.relations.forEach(subRelation => {
                 if (subRelation.isEager) {
                     processRelation(
                         relationMetadata.inverseEntityMetadata,
-                        currentMetadataIsTree,
+                        propagatedTreeContext,
                         subRelation.propertyPath,
                         nextAlias,
                         [fullPath],
@@ -147,7 +155,7 @@ export function joinTreeRelationsDynamically<T extends VendureEntity>(
         if (nextPath) {
             processRelation(
                 relationMetadata.inverseEntityMetadata,
-                currentMetadataIsTree,
+                propagatedTreeContext,
                 nextPath,
                 nextAlias,
                 [fullPath],