Improving queries

This commit is contained in:
luca.frosini 2023-11-09 12:53:35 +01:00
parent 996997804a
commit 00e0fc2a55
3 changed files with 222 additions and 210 deletions

View File

@ -167,6 +167,7 @@ public abstract class ElementManagement<El extends OElement, T extends Type> {
this.ignoreStartWithKeys = new HashSet<String>(); this.ignoreStartWithKeys = new HashSet<String>();
this.ignoreStartWithKeys.add(ElementManagement.AT); this.ignoreStartWithKeys.add(ElementManagement.AT);
this.ignoreStartWithKeys.add(ElementManagement.UNDERSCORE); this.ignoreStartWithKeys.add(ElementManagement.UNDERSCORE);
this.ignoreStartWithKeys.add(ElementManagement.DOLLAR);
this.reload = false; this.reload = false;

View File

@ -1,11 +1,7 @@
package org.gcube.informationsystem.resourceregistry.instances.model.entities; package org.gcube.informationsystem.resourceregistry.instances.model.entities;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException; 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 org.gcube.informationsystem.types.reference.entities.EntityType;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument; 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.ODirection;
import com.orientechnologies.orient.core.record.OEdge; import com.orientechnologies.orient.core.record.OEdge;
import com.orientechnologies.orient.core.record.OElement; import com.orientechnologies.orient.core.record.OElement;
@ -563,196 +557,196 @@ public abstract class EntityManagement<E extends Entity, ET extends EntityType>
public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction, public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction,
boolean polymorphic, Map<String,String> constraint, boolean includeRelationInResult) throws ResourceRegistryException { boolean polymorphic, Map<String,String> constraint, boolean includeRelationInResult) throws ResourceRegistryException {
*/ */
public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction, // public String reallyQuery(String relationType, String referenceType, UUID referenceUUID, ODirection direction,
boolean polymorphic, Map<String,String> constraint) throws ResourceRegistryException { // boolean polymorphic, Map<String,String> constraint) throws ResourceRegistryException {
ObjectMapper objectMapper = new ObjectMapper(); // ObjectMapper objectMapper = new ObjectMapper();
ArrayNode arrayNode = objectMapper.createArrayNode(); // ArrayNode arrayNode = objectMapper.createArrayNode();
//
ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get(); // ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get();
int limit = requestInfo.getLimit(); // int limit = requestInfo.getLimit();
int offset = requestInfo.getOffset(); // int offset = requestInfo.getOffset();
//
int position = -1; // int position = -1;
int count = 0; // int count = 0;
//
Iterable<?> references = null; // Iterable<?> references = null;
//
if(referenceUUID != null) { // if(referenceUUID != null) {
OElement element = null; // OElement element = null;
try { // try {
element = ElementManagementUtility.getAnyElementByUUID(oDatabaseDocument, referenceUUID); // element = ElementManagementUtility.getAnyElementByUUID(oDatabaseDocument, referenceUUID);
}catch (ResourceRegistryException e) { // }catch (ResourceRegistryException e) {
String error = String.format("No instace with UUID %s exists", referenceUUID.toString()); // String error = String.format("No instace with UUID %s exists", referenceUUID.toString());
throw new InvalidQueryException(error); // throw new InvalidQueryException(error);
} // }
//
if(element instanceof OVertex) { // if(element instanceof OVertex) {
EntityManagement<?, ?> entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(), // EntityManagement<?, ?> entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(),
oDatabaseDocument, (OVertex) element); // oDatabaseDocument, (OVertex) element);
//
String elementType = entityManagement.getTypeName(); // String elementType = entityManagement.getTypeName();
if(elementType.compareTo(referenceType) != 0) { // if(elementType.compareTo(referenceType) != 0) {
if(polymorphic && getOClass().isSubClassOf(referenceType)) { // if(polymorphic && getOClass().isSubClassOf(referenceType)) {
// OK // // OK
} else { // } else {
String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType); // String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType);
throw new InvalidQueryException(error); // throw new InvalidQueryException(error);
} // }
} // }
//
List<OVertex> vertexes = new ArrayList<>(); // List<OVertex> vertexes = new ArrayList<>();
vertexes.add((OVertex) element); // vertexes.add((OVertex) element);
references = vertexes; // references = vertexes;
//
} else { // } else {
String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType); // String error = String.format("Referenced instance with UUID %s is not a %s", referenceUUID, referenceType);
throw new InvalidQueryException(error); // throw new InvalidQueryException(error);
} // }
//
} else { // } else {
references = oDatabaseDocument.browseClass(referenceType, polymorphic); // references = oDatabaseDocument.browseClass(referenceType, polymorphic);
} // }
//
Set<ORID> analysed = new HashSet<>(); // Set<ORID> analysed = new HashSet<>();
//
outerloop: // outerloop:
for(Object r : references) { // for(Object r : references) {
OVertex v = (OVertex) r; // OVertex v = (OVertex) r;
//
boolean skip = false; // boolean skip = false;
// checking if the constraints are satisfied // // checking if the constraints are satisfied
for(String key : constraint.keySet()) { // for(String key : constraint.keySet()) {
String value = constraint.get(key); // String value = constraint.get(key);
Object o = v.getProperty(key); // Object o = v.getProperty(key);
if(value==null) { // if(value==null) {
if(o==null) { // if(o==null) {
//ok // //ok
}else { // }else {
skip = true; // skip = true;
break; // break;
} // }
}else { // }else {
if(o==null) { // if(o==null) {
// The vertex has not a required property to be tested // // The vertex has not a required property to be tested
// or the property is null // // or the property is null
skip = true; // skip = true;
break; // break;
}else { // }else {
skip = !propertyMatchRequestedValue(v, key, value, o); // skip = !propertyMatchRequestedValue(v, key, value, o);
if(skip) { // if(skip) {
break; // break;
} // }
} // }
} // }
} // }
//
if(skip) { // if(skip) {
continue; // continue;
} // }
//
//
List<ODirection> directions = new ArrayList<>(); // List<ODirection> directions = new ArrayList<>();
if(direction==ODirection.BOTH) { // if(direction==ODirection.BOTH) {
directions.add(ODirection.IN); // directions.add(ODirection.IN);
directions.add(ODirection.OUT); // directions.add(ODirection.OUT);
}else { // }else {
directions.add(direction); // directions.add(direction);
} // }
//
for(ODirection d : directions) { // for(ODirection d : directions) {
//
Iterable<OEdge> edges = v.getEdges(d.opposite(), relationType); // Iterable<OEdge> edges = v.getEdges(d.opposite(), relationType);
for(OEdge edge : edges) { // for(OEdge edge : edges) {
OVertex vertex = edge.getVertex(d); // OVertex vertex = edge.getVertex(d);
//
ORID vertexORID = vertex.getIdentity(); // ORID vertexORID = vertex.getIdentity();
//
if(analysed.contains(vertexORID)) { // if(analysed.contains(vertexORID)) {
continue; // continue;
} // }
analysed.add(vertexORID); // analysed.add(vertexORID);
//
if(v.getIdentity().compareTo(vertexORID) == 0) { // if(v.getIdentity().compareTo(vertexORID) == 0) {
continue; // continue;
} // }
//
OClass oClass = ElementManagementUtility.getOClass(vertex); // OClass oClass = ElementManagementUtility.getOClass(vertex);
//
/* // /*
* If the requested type (i.e. elementType) // * If the requested type (i.e. elementType)
* differs form the resulting type (i.e. oClass.getName()) // * differs form the resulting type (i.e. oClass.getName())
* we need to evaluate if polymorphism is requested and // * we need to evaluate if polymorphism is requested and
* if the resulting type is a subclass of the requested type // * if the resulting type is a subclass of the requested type
* // *
*/ // */
if(oClass.getName().compareTo(typeName)!=0) { // if(oClass.getName().compareTo(typeName)!=0) {
if(polymorphic && oClass.isSubClassOf(typeName)) { // if(polymorphic && oClass.isSubClassOf(typeName)) {
// OK // // OK
} else { // } else {
// excluding from results // // excluding from results
continue; // continue;
} // }
} // }
//
//
//
EntityManagement<?,?> entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(), // EntityManagement<?,?> entityManagement = ElementManagementUtility.getEntityManagement(getWorkingContext(),
oDatabaseDocument, vertex); // oDatabaseDocument, vertex);
//
try { // try {
if(referenceUUID!=null && entityManagement.getUUID().compareTo(referenceUUID) == 0) { // if(referenceUUID!=null && entityManagement.getUUID().compareTo(referenceUUID) == 0) {
continue; // continue;
} // }
//
//
/* // /*
* This is the only position where we can put // * This is the only position where we can put
* pagination check because we need matching results // * pagination check because we need matching results
*/ // */
if(++position < offset) { // if(++position < offset) {
continue; // continue;
} // }
//
/* // /*
JsonNode jsonNode; // JsonNode jsonNode;
if(includeRelationInResult) { // if(includeRelationInResult) {
RelationManagement<?,?> relationManagement = ElementManagementUtility.getRelationManagement(getWorkingContext(), // RelationManagement<?,?> relationManagement = ElementManagementUtility.getRelationManagement(getWorkingContext(),
oDatabaseDocument, edge); // oDatabaseDocument, edge);
jsonNode = relationManagement.serializeAsJsonNode(); // jsonNode = relationManagement.serializeAsJsonNode();
}else { // }else {
jsonNode = entityManagement.serializeAsJsonNode(); // jsonNode = entityManagement.serializeAsJsonNode();
} // }
*/ // */
entityManagement.setAsEntryPoint(); // entityManagement.setAsEntryPoint();
//
//
JsonNode node = entityManagement.serializeAsJsonNode(); // JsonNode node = entityManagement.serializeAsJsonNode();
arrayNode.add(node); // arrayNode.add(node);
//
/* // /*
* This is the only position where we can put // * This is the only position where we can put
* pagination check because we need matching results // * pagination check because we need matching results
*/ // */
if(limit > 0 && ++count >= limit) { // if(limit > 0 && ++count >= limit) {
break outerloop; // break outerloop;
} // }
//
} catch(ResourceRegistryException e) { // } catch(ResourceRegistryException e) {
logger.error("Unable to correctly serialize {}. It will be excluded from results. {}", // logger.error("Unable to correctly serialize {}. It will be excluded from results. {}",
vertex.toString(), OrientDBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE); // vertex.toString(), OrientDBUtility.SHOULD_NOT_OCCUR_ERROR_MESSAGE);
} // }
} // }
} // }
} // }
//
try { // try {
return objectMapper.writeValueAsString(arrayNode); // return objectMapper.writeValueAsString(arrayNode);
} catch(JsonProcessingException e) { // } catch(JsonProcessingException e) {
throw new ResourceRegistryException(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<String,String> constraint) throws ResourceRegistryException { ODirection direction, boolean polymorphic, Map<String,String> constraint) throws ResourceRegistryException {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
ArrayNode arrayNode = objectMapper.createArrayNode(); ArrayNode arrayNode = objectMapper.createArrayNode();
@ -761,24 +755,33 @@ public abstract class EntityManagement<E extends Entity, ET extends EntityType>
constraint.put(Entity.ID_PROPERTY, referenceUUID.toString()); constraint.put(Entity.ID_PROPERTY, referenceUUID.toString());
} }
// TODO check types
/* /*
* SELECT FROM (TRAVERSE inE('isIdentifiedBy'), outV('EService') FROM (SELECT * SELECT FROM (
* FROM SoftwareFacet WHERE group='VREManagement' AND name='SmartExecutor')) * 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 "); 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(direction.opposite().name().toLowerCase());
selectStringBuilder.append("V('"); selectStringBuilder.append("V('");
selectStringBuilder.append(typeName); 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); selectStringBuilder.append(referenceType);
boolean first = true; boolean first = true;
for(String key : constraint.keySet()) { for(String key : constraint.keySet()) {
@ -797,11 +800,16 @@ public abstract class EntityManagement<E extends Entity, ET extends EntityType>
} }
selectStringBuilder.append(" ))"); selectStringBuilder.append(" ))");
if(!polymorphic) {
selectStringBuilder.append(" WHERE type='"); selectStringBuilder.append(" WHERE @class");
selectStringBuilder.append(typeName); if(polymorphic) {
selectStringBuilder.append("'"); selectStringBuilder.append(" INSTANCEOF ");
} else {
selectStringBuilder.append("='");
} }
selectStringBuilder.append(typeName);
selectStringBuilder.append("'");
String select = selectStringBuilder.toString(); String select = selectStringBuilder.toString();
logger.trace(select); logger.trace(select);
@ -812,6 +820,7 @@ public abstract class EntityManagement<E extends Entity, ET extends EntityType>
OResult oResult = resultSet.next(); OResult oResult = resultSet.next();
OElement element = ElementManagementUtility.getElementFromOptional(oResult.getElement()); OElement element = ElementManagementUtility.getElementFromOptional(oResult.getElement());
/*
if(polymorphic) { if(polymorphic) {
OClass oClass = null; OClass oClass = null;
try { try {
@ -831,6 +840,7 @@ public abstract class EntityManagement<E extends Entity, ET extends EntityType>
} }
} }
*/
OVertex vertex = (OVertex) element; OVertex vertex = (OVertex) element;

View File

@ -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.contexts.ContextNotFoundException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.queries.InvalidQueryException; import org.gcube.informationsystem.resourceregistry.api.exceptions.queries.InvalidQueryException;
import org.gcube.informationsystem.resourceregistry.api.exceptions.types.SchemaNotFoundException; 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.AccessPath;
import org.gcube.informationsystem.resourceregistry.api.rest.ContextPath; import org.gcube.informationsystem.resourceregistry.api.rest.ContextPath;
import org.gcube.informationsystem.resourceregistry.api.rest.InstancePath; 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); 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); 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.setAllMeta(true);
serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER); serverRequestInfo.checkBooleanQueryParameter(ContextPath.INCLUDE_META_QUERY_PARAMETER);
serverRequestInfo.checkLimitOffset(); serverRequestInfo.checkLimitOffset();