Commit 77d754ad90941a9d1468f1af91b5c70bc4a127c9

Authored by Andrii Shvaika
1 parent 0cc52cd1

Fetch Last Level Only improvement

... ... @@ -467,9 +467,20 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
467 467 ctx.addStringParameter("where_relation_type", entityFilter.getRelationType());
468 468 whereFilter += " re.relation_type = :where_relation_type AND";
469 469 }
  470 + String toOrFrom = (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from");
470 471 whereFilter += " re." + (entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from") + "_type = :where_entity_type";
471 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 485 from = String.format(from, lvlFilter, whereFilter);
475 486 String query = "( " + selectFields + from + ")";
... ... @@ -502,14 +513,13 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
502 513 StringBuilder whereFilter = new StringBuilder();
503 514
504 515 boolean noConditions = true;
  516 + boolean single = entityFilter.getFilters() != null && entityFilter.getFilters().size() == 1;
505 517 if (entityFilter.getFilters() != null && !entityFilter.getFilters().isEmpty()) {
506   - boolean single = entityFilter.getFilters().size() == 1;
507 518 int entityTypeFilterIdx = 0;
508 519 for (EntityTypeFilter etf : entityFilter.getFilters()) {
509 520 String etfCondition = buildEtfCondition(ctx, etf, entityFilter.getDirection(), entityTypeFilterIdx++);
510 521 if (!etfCondition.isEmpty()) {
511 522 if (noConditions) {
512   - whereFilter.append(" WHERE ");
513 523 noConditions = false;
514 524 } else {
515 525 whereFilter.append(" OR ");
... ... @@ -525,15 +535,33 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository {
525 535 }
526 536 }
527 537 if (noConditions) {
528   - whereFilter.append(" WHERE re.")
  538 + whereFilter.append(" re.")
529 539 .append(entityFilter.getDirection().equals(EntitySearchDirection.FROM) ? "to" : "from")
530 540 .append("_type in (:where_entity_types").append(")");
531 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 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 565 return "( " + selectFields + from + ")";
538 566 }
539 567
... ...