From 00e0fc2a5579be35ff762b449dca2e1e55385e74 Mon Sep 17 00:00:00 2001 From: "luca.frosini" Date: Thu, 9 Nov 2023 12:53:35 +0100 Subject: [PATCH] Improving queries --- .../instances/base/ElementManagement.java | 1 + .../model/entities/EntityManagement.java | 428 +++++++++--------- .../resourceregistry/rest/Access.java | 3 +- 3 files changed, 222 insertions(+), 210 deletions(-) diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java index 74f2621..fdb9b4b 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/base/ElementManagement.java @@ -167,6 +167,7 @@ public abstract class ElementManagement { this.ignoreStartWithKeys = new HashSet(); this.ignoreStartWithKeys.add(ElementManagement.AT); this.ignoreStartWithKeys.add(ElementManagement.UNDERSCORE); + this.ignoreStartWithKeys.add(ElementManagement.DOLLAR); this.reload = false; diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java index ac5077c..27ca50c 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/instances/model/entities/EntityManagement.java @@ -1,11 +1,7 @@ package org.gcube.informationsystem.resourceregistry.instances.model.entities; -import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; import org.gcube.com.fasterxml.jackson.core.JsonProcessingException; @@ -46,8 +42,6 @@ import org.gcube.informationsystem.resourceregistry.utils.OrientDBUtility; import org.gcube.informationsystem.types.reference.entities.EntityType; import com.orientechnologies.orient.core.db.document.ODatabaseDocument; -import com.orientechnologies.orient.core.id.ORID; -import com.orientechnologies.orient.core.metadata.schema.OClass; import com.orientechnologies.orient.core.record.ODirection; import com.orientechnologies.orient.core.record.OEdge; import com.orientechnologies.orient.core.record.OElement; @@ -563,196 +557,196 @@ public abstract class EntityManagement public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction, boolean polymorphic, Map constraint, boolean includeRelationInResult) throws ResourceRegistryException { */ - public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction, - boolean polymorphic, Map constraint) throws ResourceRegistryException { - ObjectMapper objectMapper = new ObjectMapper(); - ArrayNode arrayNode = objectMapper.createArrayNode(); - - ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); - int limit = requestInfo.getLimit(); - int offset = requestInfo.getOffset(); - - int position = -1; - int count = 0; - - Iterable references = null; - - if(referenceUUID != null) { - OElement element = null; - try { - element = ElementManagementUtility.getAnyElementByUUID(oDatabaseDocument, referenceUUID); - }catch (ResourceRegistryException e) { - String error = String.format("No instace with UUID %s exists", referenceUUID.toString()); - throw new InvalidQueryException(error); - } - - if(element instanceof OVertex) { - EntityManagement entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(), - oDatabaseDocument, (OVertex) element); - - String elementType = entityManagement.getTypeName(); - if(elementType.compareTo(referenceType) != 0) { - if(polymorphic && getOClass().isSubClassOf(referenceType)) { - // OK - } else { - String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType); - throw new InvalidQueryException(error); - } - } - - List vertexes = new ArrayList<>(); - vertexes.add((OVertex) element); - references = vertexes; - - } else { - String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType); - throw new InvalidQueryException(error); - } - - } else { - references = oDatabaseDocument.browseClass(referenceType, polymorphic); - } - - Set analysed = new HashSet<>(); - - outerloop: - for(Object r : references) { - OVertex v = (OVertex) r; - - boolean skip = false; - // checking if the constraints are satisfied - for(String key : constraint.keySet()) { - String value = constraint.get(key); - Object o = v.getProperty(key); - if(value==null) { - if(o==null) { - //ok - }else { - skip = true; - break; - } - }else { - if(o==null) { - // The vertex has not a required property to be tested - // or the property is null - skip = true; - break; - }else { - skip = !propertyMatchRequestedValue(v, key, value, o); - if(skip) { - break; - } - } - } - } - - if(skip) { - continue; - } - - - List directions = new ArrayList<>(); - if(direction==ODirection.BOTH) { - directions.add(ODirection.IN); - directions.add(ODirection.OUT); - }else { - directions.add(direction); - } - - for(ODirection d : directions) { - - Iterable edges = v.getEdges(d.opposite(), relationType); - for(OEdge edge : edges) { - OVertex vertex = edge.getVertex(d); - - ORID vertexORID = vertex.getIdentity(); - - if(analysed.contains(vertexORID)) { - continue; - } - analysed.add(vertexORID); - - if(v.getIdentity().compareTo(vertexORID) == 0) { - continue; - } - - OClass oClass = ElementManagementUtility.getOClass(vertex); - - /* - * If the requested type (i.e. elementType) - * differs form the resulting type (i.e. oClass.getName()) - * we need to evaluate if polymorphism is requested and - * if the resulting type is a subclass of the requested type - * - */ - if(oClass.getName().compareTo(typeName)!=0) { - if(polymorphic && oClass.isSubClassOf(typeName)) { - // OK - } else { - // excluding from results - continue; - } - } - - - - EntityManagement entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(), - oDatabaseDocument, vertex); - - try { - if(referenceUUID!=null && entityManagement.getUUID().compareTo(referenceUUID) == 0) { - continue; - } - - - /* - * This is the only position where we can put - * pagination check because we need matching results - */ - if(++position < offset) { - continue; - } - - /* - JsonNode jsonNode; - if(includeRelationInResult) { - RelationManagement relationManagement = ElementManagementUtility.getRelationManagement(getWorkingContext(), - oDatabaseDocument, edge); - jsonNode = relationManagement.serializeAsJsonNode(); - }else { - jsonNode = entityManagement.serializeAsJsonNode(); - } - */ - entityManagement.setAsEntryPoint(); - - - JsonNode node = entityManagement.serializeAsJsonNode(); - arrayNode.add(node); - - /* - * This is the only position where we can put - * pagination check because we need matching results - */ - if(limit > 0 && ++count >= limit) { - break outerloop; - } - - } catch(ResourceRegistryException e) { - logger.error("Unable to correctly serialize {}. It will be excluded from results. {}", - vertex.toString(), OrientDBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE); - } - } - } - } - - try { - return objectMapper.writeValueAsString(arrayNode); - } catch(JsonProcessingException e) { - throw new ResourceRegistryException(e); - } - } +// public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction, +// boolean polymorphic, Map constraint) throws ResourceRegistryException { +// ObjectMapper objectMapper = new ObjectMapper(); +// ArrayNode arrayNode = objectMapper.createArrayNode(); +// +// ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); +// int limit = requestInfo.getLimit(); +// int offset = requestInfo.getOffset(); +// +// int position = -1; +// int count = 0; +// +// Iterable references = null; +// +// if(referenceUUID != null) { +// OElement element = null; +// try { +// element = ElementManagementUtility.getAnyElementByUUID(oDatabaseDocument, referenceUUID); +// }catch (ResourceRegistryException e) { +// String error = String.format("No instace with UUID %s exists", referenceUUID.toString()); +// throw new InvalidQueryException(error); +// } +// +// if(element instanceof OVertex) { +// EntityManagement entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(), +// oDatabaseDocument, (OVertex) element); +// +// String elementType = entityManagement.getTypeName(); +// if(elementType.compareTo(referenceType) != 0) { +// if(polymorphic && getOClass().isSubClassOf(referenceType)) { +// // OK +// } else { +// String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType); +// throw new InvalidQueryException(error); +// } +// } +// +// List vertexes = new ArrayList<>(); +// vertexes.add((OVertex) element); +// references = vertexes; +// +// } else { +// String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType); +// throw new InvalidQueryException(error); +// } +// +// } else { +// references = oDatabaseDocument.browseClass(referenceType, polymorphic); +// } +// +// Set analysed = new HashSet<>(); +// +// outerloop: +// for(Object r : references) { +// OVertex v = (OVertex) r; +// +// boolean skip = false; +// // checking if the constraints are satisfied +// for(String key : constraint.keySet()) { +// String value = constraint.get(key); +// Object o = v.getProperty(key); +// if(value==null) { +// if(o==null) { +// //ok +// }else { +// skip = true; +// break; +// } +// }else { +// if(o==null) { +// // The vertex has not a required property to be tested +// // or the property is null +// skip = true; +// break; +// }else { +// skip = !propertyMatchRequestedValue(v, key, value, o); +// if(skip) { +// break; +// } +// } +// } +// } +// +// if(skip) { +// continue; +// } +// +// +// List directions = new ArrayList<>(); +// if(direction==ODirection.BOTH) { +// directions.add(ODirection.IN); +// directions.add(ODirection.OUT); +// }else { +// directions.add(direction); +// } +// +// for(ODirection d : directions) { +// +// Iterable edges = v.getEdges(d.opposite(), relationType); +// for(OEdge edge : edges) { +// OVertex vertex = edge.getVertex(d); +// +// ORID vertexORID = vertex.getIdentity(); +// +// if(analysed.contains(vertexORID)) { +// continue; +// } +// analysed.add(vertexORID); +// +// if(v.getIdentity().compareTo(vertexORID) == 0) { +// continue; +// } +// +// OClass oClass = ElementManagementUtility.getOClass(vertex); +// +// /* +// * If the requested type (i.e. elementType) +// * differs form the resulting type (i.e. oClass.getName()) +// * we need to evaluate if polymorphism is requested and +// * if the resulting type is a subclass of the requested type +// * +// */ +// if(oClass.getName().compareTo(typeName)!=0) { +// if(polymorphic && oClass.isSubClassOf(typeName)) { +// // OK +// } else { +// // excluding from results +// continue; +// } +// } +// +// +// +// EntityManagement entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(), +// oDatabaseDocument, vertex); +// +// try { +// if(referenceUUID!=null && entityManagement.getUUID().compareTo(referenceUUID) == 0) { +// continue; +// } +// +// +// /* +// * This is the only position where we can put +// * pagination check because we need matching results +// */ +// if(++position < offset) { +// continue; +// } +// +// /* +// JsonNode jsonNode; +// if(includeRelationInResult) { +// RelationManagement relationManagement = ElementManagementUtility.getRelationManagement(getWorkingContext(), +// oDatabaseDocument, edge); +// jsonNode = relationManagement.serializeAsJsonNode(); +// }else { +// jsonNode = entityManagement.serializeAsJsonNode(); +// } +// */ +// entityManagement.setAsEntryPoint(); +// +// +// JsonNode node = entityManagement.serializeAsJsonNode(); +// arrayNode.add(node); +// +// /* +// * This is the only position where we can put +// * pagination check because we need matching results +// */ +// if(limit > 0 && ++count >= limit) { +// break outerloop; +// } +// +// } catch(ResourceRegistryException e) { +// logger.error("Unable to correctly serialize {}. It will be excluded from results. {}", +// vertex.toString(), OrientDBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE); +// } +// } +// } +// } +// +// try { +// return objectMapper.writeValueAsString(arrayNode); +// } catch(JsonProcessingException e) { +// throw new ResourceRegistryException(e); +// } +// } - public String reallyQueryTraversal(String relationType, String referenceType, UUID referenceUUID, + public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction, boolean polymorphic, Map constraint) throws ResourceRegistryException { ObjectMapper objectMapper = new ObjectMapper(); ArrayNode arrayNode = objectMapper.createArrayNode(); @@ -761,24 +755,33 @@ public abstract class EntityManagement constraint.put(Entity.ID_PROPERTY, referenceUUID.toString()); } - // TODO check types - /* - * SELECT FROM (TRAVERSE inE('isIdentifiedBy'), outV('EService') FROM (SELECT - * FROM SoftwareFacet WHERE group='VREManagement' AND name='SmartExecutor')) + * SELECT FROM ( + * TRAVERSE outV('EService'), inE('isIdentifiedBy') FROM ( + * SELECT FROM SoftwareFacet WHERE group='VREManagement' AND name='SmartExecutor' + * ) + * ) * - * WHERE type='EService' // Only is not polymorphic + * WHERE @class INSTANCEOF 'EService' // if polymorphic is true + * + * WHERE @class='EService' // if polymorphic is false */ StringBuilder selectStringBuilder = new StringBuilder("SELECT FROM (TRAVERSE "); - selectStringBuilder.append(direction.name().toLowerCase()); - selectStringBuilder.append("E('"); - selectStringBuilder.append(relationType); - selectStringBuilder.append("'), "); + selectStringBuilder.append(direction.opposite().name().toLowerCase()); selectStringBuilder.append("V('"); selectStringBuilder.append(typeName); - selectStringBuilder.append("') FROM (SELECT FROM "); + selectStringBuilder.append("')"); + + selectStringBuilder.append(", "); + + selectStringBuilder.append(direction.name().toLowerCase()); + selectStringBuilder.append("E('"); + selectStringBuilder.append(relationType); + selectStringBuilder.append("')"); + + selectStringBuilder.append(" FROM (SELECT FROM "); selectStringBuilder.append(referenceType); boolean first = true; for(String key : constraint.keySet()) { @@ -797,11 +800,16 @@ public abstract class EntityManagement } selectStringBuilder.append(" ))"); - if(!polymorphic) { - selectStringBuilder.append(" WHERE type='"); - selectStringBuilder.append(typeName); - selectStringBuilder.append("'"); + + selectStringBuilder.append(" WHERE @class"); + if(polymorphic) { + selectStringBuilder.append(" INSTANCEOF "); + } else { + selectStringBuilder.append("='"); } + selectStringBuilder.append(typeName); + selectStringBuilder.append("'"); + String select = selectStringBuilder.toString(); logger.trace(select); @@ -812,6 +820,7 @@ public abstract class EntityManagement OResult oResult = resultSet.next(); OElement element = ElementManagementUtility.getElementFromOptional(oResult.getElement()); + /* if(polymorphic) { OClass oClass = null; try { @@ -831,6 +840,7 @@ public abstract class EntityManagement } } + */ OVertex vertex = (OVertex) element; diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java index 8460aba..3fc245b 100644 --- a/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/rest/Access.java @@ -30,6 +30,7 @@ import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegis import org.gcube.informationsystem.resourceregistry.api.exceptions.contexts.ContextNotFoundException; import org.gcube.informationsystem.resourceregistry.api.exceptions.queries.InvalidQueryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaNotFoundException; +import org.gcube.informationsystem.resourceregistry.api.request.BaseRequestInfo; import org.gcube.informationsystem.resourceregistry.api.rest.AccessPath; import org.gcube.informationsystem.resourceregistry.api.rest.ContextPath; import org.gcube.informationsystem.resourceregistry.api.rest.InstancePath; @@ -79,7 +80,7 @@ public class Access extends BaseRest { logger.info("Requested to read all {}s", org.gcube.informationsystem.contexts.reference.entities.Context.NAME); setAccountingMethod(Method.LIST, org.gcube.informationsystem.contexts.reference.entities.Context.NAME); - ServerRequestInfo serverRequestInfo = initRequestInfo(); + ServerRequestInfo serverRequestInfo = initRequestInfo(BaseRequestInfo.DEFAULT_OFFSET, BaseRequestInfo.UNBOUNDED_LIMIT); serverRequestInfo.setAllMeta(true); serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER); serverRequestInfo.checkLimitOffset();