Commit 77d754ad90941a9d1468f1af91b5c70bc4a127c9

Authored by Andrii Shvaika
1 parent 0cc52cd1

Fetch Last Level Only improvement

@@ -467,9 +467,20 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { @@ -467,9 +467,20 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
467 ctx.addStringParameter("where_relation_type", entityFilter.getRelationType()); 467 ctx.addStringParameter("where_relation_type", entityFilter.getRelationType());
468 whereFilter += " re.relation_type = :where_relation_type AND"; 468 whereFilter += " re.relation_type = :where_relation_type AND";
469 } 469 }
  470 + String toOrFrom = (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from");
470 whereFilter += " re." + (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from") + "_type = :where_entity_type"; 471 whereFilter += " re." + (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from") + "_type = :where_entity_type";
471 if (entityFilter.isFetchLastLevelOnly()) { 472 if (entityFilter.isFetchLastLevelOnly()) {
472 - whereFilter += " and re.lvl = " + entityFilter.getMaxLevel(); 473 + String fromOrTo = (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "from" : "to");
  474 + StringBuilder notExistsPart = new StringBuilder();
  475 + notExistsPart.append(" NOT EXISTS (SELECT 1 from relation nr where ")
  476 + .append("nr.").append(fromOrTo).append("_id").append(" = re.").append(toOrFrom).append("_id")
  477 + .append(" and ")
  478 + .append("nr.").append(fromOrTo).append("_type").append(" = re.").append(toOrFrom).append("_type");
  479 + if (!StringUtils.isEmpty(entityFilter.getRelationType())) {
  480 + notExistsPart.append(" and nr.relation_type = :where_relation_type");
  481 + }
  482 + notExistsPart.append(")");
  483 + whereFilter += " and ( re.lvl = " + entityFilter.getMaxLevel() + " OR " + notExistsPart.toString() + ")";
473 } 484 }
474 from = String.format(from, lvlFilter, whereFilter); 485 from = String.format(from, lvlFilter, whereFilter);
475 String query = "( " + selectFields + from + ")"; 486 String query = "( " + selectFields + from + ")";
@@ -502,14 +513,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { @@ -502,14 +513,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
502 StringBuilder whereFilter = new StringBuilder(); 513 StringBuilder whereFilter = new StringBuilder();
503 514
504 boolean noConditions = true; 515 boolean noConditions = true;
  516 + boolean single = entityFilter.getFilters() != null && entityFilter.getFilters().size() == 1;
505 if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) { 517 if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) {
506 - boolean single = entityFilter.getFilters().size() == 1;  
507 int entityTypeFilterIdx = 0; 518 int entityTypeFilterIdx = 0;
508 for (EntityTypeFilter etf : entityFilter.getFilters()) { 519 for (EntityTypeFilter etf : entityFilter.getFilters()) {
509 String etfCondition = buildEtfCondition(ctx, etf, entityFilter.getDirection(), entityTypeFilterIdx++); 520 String etfCondition = buildEtfCondition(ctx, etf, entityFilter.getDirection(), entityTypeFilterIdx++);
510 if (!etfCondition.isEmpty()) { 521 if (!etfCondition.isEmpty()) {
511 if (noConditions) { 522 if (noConditions) {
512 - whereFilter.append(" WHERE ");  
513 noConditions = false; 523 noConditions = false;
514 } else { 524 } else {
515 whereFilter.append(" OR "); 525 whereFilter.append(" OR ");
@@ -525,15 +535,33 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { @@ -525,15 +535,33 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
525 } 535 }
526 } 536 }
527 if (noConditions) { 537 if (noConditions) {
528 - whereFilter.append(" WHERE re.") 538 + whereFilter.append(" re.")
529 .append(entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from") 539 .append(entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from")
530 .append("_type in (:where_entity_types").append(")"); 540 .append("_type in (:where_entity_types").append(")");
531 ctx.addStringListParameter("where_entity_types", Arrays.stream(RELATION_QUERY_ENTITY_TYPES).map(EntityType::name).collect(Collectors.toList())); 541 ctx.addStringListParameter("where_entity_types", Arrays.stream(RELATION_QUERY_ENTITY_TYPES).map(EntityType::name).collect(Collectors.toList()));
532 } 542 }
  543 +
  544 + if (!noConditions && !single) {
  545 + whereFilter = new StringBuilder().append("(").append(whereFilter).append(")");
  546 + }
  547 +
533 if (entityFilter.isFetchLastLevelOnly()) { 548 if (entityFilter.isFetchLastLevelOnly()) {
534 - whereFilter.append(" and re.lvl = ").append(entityFilter.getMaxLevel()); 549 + String toOrFrom = (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from");
  550 + String fromOrTo = (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "from" : "to");
  551 +
  552 + StringBuilder notExistsPart = new StringBuilder();
  553 + notExistsPart.append(" NOT EXISTS (SELECT 1 from relation nr WHERE ");
  554 + notExistsPart.append(whereFilter.toString());
  555 + notExistsPart
  556 + .append(" and ")
  557 + .append("nr.").append(fromOrTo).append("_id").append(" = re.").append(toOrFrom).append("_id")
  558 + .append(" and ")
  559 + .append("nr.").append(fromOrTo).append("_type").append(" = re.").append(toOrFrom).append("_type");
  560 +
  561 + notExistsPart.append(")");
  562 + whereFilter.append(" and ( re.lvl = ").append(entityFilter.getMaxLevel()).append(" OR ").append(notExistsPart.toString()).append(")");
535 } 563 }
536 - from = String.format(from, lvlFilter, whereFilter); 564 + from = String.format(from, lvlFilter, " WHERE " + whereFilter);
537 return "( " + selectFields + from + ")"; 565 return "( " + selectFields + from + ")";
538 } 566 }
539 567