diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java index cd06bf7537f..c040a9376ec 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/CollectionDAO.java @@ -1765,6 +1765,51 @@ public interface CollectionDAO { default String getNameHashColumn() { return "fqnHash"; } + + @Override + default int listCount(ListFilter filter) { + String condition = filter.getCondition(); + String directChildrenOf = filter.getQueryParam("directChildrenOf"); + + if (!nullOrEmpty(directChildrenOf)) { + condition = + String.format( + " %s AND fqnHash = CONCAT('%s', '.', MD5( IF(name LIKE '%%.%%', CONCAT('\"', name, '\"'), name))) ", + condition, FullyQualifiedName.buildHash(directChildrenOf)); + } + + return listCount(getTableName(), getNameHashColumn(), condition); + } + + @Override + default List listBefore(ListFilter filter, int limit, String before) { + String condition = filter.getCondition(); + String directChildrenOf = filter.getQueryParam("directChildrenOf"); + + if (!nullOrEmpty(directChildrenOf)) { + condition = + String.format( + " %s AND fqnHash = CONCAT('%s', '.', MD5( IF(name LIKE '%%.%%', CONCAT('\"', name, '\"'), name))) ", + condition, FullyQualifiedName.buildHash(directChildrenOf)); + } + + return listBefore(getTableName(), condition, limit, before); + } + + @Override + default List listAfter(ListFilter filter, int limit, String after) { + String condition = filter.getCondition(); + String directChildrenOf = filter.getQueryParam("directChildrenOf"); + + if (!nullOrEmpty(directChildrenOf)) { + condition = + String.format( + " %s AND fqnHash = CONCAT('%s', '.', MD5( IF(name LIKE '%%.%%', CONCAT('\"', name, '\"'), name))) ", + condition, FullyQualifiedName.buildHash(directChildrenOf)); + } + + return listAfter(getTableName(), condition, limit, after); + } } interface IngestionPipelineDAO extends EntityDAO { diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/GlossaryTermRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/GlossaryTermRepository.java index 3771aab5a5b..29b44764eb8 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/GlossaryTermRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/GlossaryTermRepository.java @@ -118,12 +118,15 @@ public class GlossaryTermRepository extends EntityRepository { fields.contains("relatedTerms") ? getRelatedTerms(entity) : entity.getRelatedTerms()); entity.withUsageCount( fields.contains("usageCount") ? getUsageCount(entity) : entity.getUsageCount()); + entity.withChildrenCount( + fields.contains("childrenCount") ? getChildrenCount(entity) : entity.getChildrenCount()); } @Override public void clearFields(GlossaryTerm entity, Fields fields) { entity.setRelatedTerms(fields.contains("relatedTerms") ? entity.getRelatedTerms() : null); entity.withUsageCount(fields.contains("usageCount") ? entity.getUsageCount() : null); + entity.withChildrenCount(fields.contains("childrenCount") ? entity.getChildrenCount() : null); } @Override @@ -140,6 +143,13 @@ public class GlossaryTermRepository extends EntityRepository { .getTagCount(TagSource.GLOSSARY.ordinal(), term.getFullyQualifiedName()); } + private Integer getChildrenCount(GlossaryTerm term) { + return daoCollection + .relationshipDAO() + .findTo(term.getId(), GLOSSARY_TERM, Relationship.CONTAINS.ordinal(), GLOSSARY_TERM) + .size(); + } + private List getRelatedTerms(GlossaryTerm entity) { return findBoth(entity.getId(), GLOSSARY_TERM, Relationship.RELATED_TO, GLOSSARY_TERM); } diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/glossary/GlossaryTermResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/glossary/GlossaryTermResource.java index 2b6b41e8366..fdfc30701d5 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/glossary/GlossaryTermResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/glossary/GlossaryTermResource.java @@ -89,7 +89,7 @@ import org.openmetadata.service.util.ResultList; public class GlossaryTermResource extends EntityResource { public static final String COLLECTION_PATH = "v1/glossaryTerms/"; static final String FIELDS = - "children,relatedTerms,reviewers,owner,tags,usageCount,domain,extension"; + "children,relatedTerms,reviewers,owner,tags,usageCount,domain,extension,childrenCount"; @Override public GlossaryTerm addHref(UriInfo uriInfo, GlossaryTerm term) { @@ -210,7 +210,14 @@ public class GlossaryTermResource extends EntityResource terms; if (before != null) { // Reverse paging diff --git a/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json index 519f87c8372..c6e6febb631 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/en/glossary_term_index_mapping.json @@ -416,6 +416,9 @@ }, "descriptionStatus": { "type": "keyword" + }, + "childrenCount": { + "type": "integer" } } } diff --git a/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json b/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json index 59db31c5c71..21771c29133 100644 --- a/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json +++ b/openmetadata-service/src/main/resources/elasticsearch/jp/glossary_term_index_mapping.json @@ -411,6 +411,9 @@ }, "descriptionStatus": { "type": "keyword" + }, + "childrenCount": { + "type": "integer" } } } diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/glossary/GlossaryTermResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/glossary/GlossaryTermResourceTest.java index 7feaa91e438..de10776acc5 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/glossary/GlossaryTermResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/glossary/GlossaryTermResourceTest.java @@ -985,6 +985,33 @@ public class GlossaryTermResourceTest extends EntityResourceTest queryParams = new HashMap<>(); + queryParams.put("directChildrenOf", term1.getFullyQualifiedName()); + List children = listEntities(queryParams, ADMIN_AUTH_HEADERS).getData(); + + assertEquals(term1.getChildren().size(), children.size()); + + for (int i = 0; i < children.size(); i++) { + GlossaryTerm responseChild = children.get(i); + GlossaryTerm child = children.get(i); + assertTrue(child.getFullyQualifiedName().startsWith(responseChild.getFullyQualifiedName())); + } + + GlossaryTerm response = getEntity(term1.getId(), "childrenCount", ADMIN_AUTH_HEADERS); + assertEquals(term1.getChildren().size(), response.getChildrenCount()); + } + public Glossary createGlossary( TestInfo test, List reviewers, EntityReference owner) throws IOException { return createGlossary(glossaryTest.getEntityName(test), reviewers, owner); diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/data/glossaryTerm.json b/openmetadata-spec/src/main/resources/json/schema/entity/data/glossaryTerm.json index 8b159634195..8b45e1e296a 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/data/glossaryTerm.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/data/glossaryTerm.json @@ -153,6 +153,10 @@ }, "votes" : { "$ref": "../../type/votes.json" + }, + "childrenCount": { + "description": "Count of immediate children glossary terms.", + "type": "integer" } }, "required": ["id", "name", "description", "glossary"],