Search in sources :

Example 1 with ValueConstraint

use of org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint in project stanbol by apache.

the class SparqlQueryUtils method addFieldConstraint.

/**
 * Adds the WHERE clause of the SPARQL query.
 * <p>
 * If the {@link SparqlEndpointTypeEnum SPARQL endpoint} supports SPARQL 1.1 subqueries, than this adds also the
 * LIMIT and OFFSET to in inner SELECT that only selects the id.
 *
 * @param queryString
 *            the SPARQL query string to add the WHERE
 * @param query
 *            the query
 * @param selectedFields
 *            the selected fields
 * @param endpointType
 *            The type of the endpoint (used to write optimised queries for endpoint type specific
 *            extensions
 */
private static void addFieldConstraint(final StringBuilder queryString, SparqlFieldQuery query, Map<String, String> selectedFields, SparqlEndpointTypeEnum endpointType) {
    // we need temporary variables with unique names
    String varPrefix = "tmp";
    int[] varNum = new int[] { 1 };
    // used to open brackets for the select part of the constraints
    boolean first = true;
    // determine if sub-selects are supported and if we need a sub-select
    // (more than the id is selected)
    boolean subSelectState = isSubSelectState(endpointType, selectedFields);
    log.trace("add field constraints is in a sub-select-state [{}].", (subSelectState ? "yes" : "no"));
    // if we uses a sub query to select the ids, we need to add the graph
    // pattern
    // of all selected fields outside of the sub query
    Map<String, String> tmpSelectedFields = subSelectState ? new HashMap<String, String>(selectedFields) : null;
    String intend;
    if (subSelectState) {
        // additional intend because of sub query (3*2)
        intend = "      ";
    } else {
        // normal intend (2*2)
        intend = "    ";
    }
    Iterator<Entry<String, Constraint>> constraintIterator = query.iterator();
    while (constraintIterator.hasNext()) {
        Entry<String, Constraint> fieldConstraint = constraintIterator.next();
        if (first) {
            queryString.append("  { \n");
            if (subSelectState) {
                String rootVarName = selectedFields.get(null);
                queryString.append("    SELECT ?").append(rootVarName).append(" \n");
                queryString.append("    WHERE { \n");
            }
            first = false;
        }
        String field = fieldConstraint.getKey();
        Constraint constraint = fieldConstraint.getValue();
        log.trace("adding a constraint [type :: {}][field :: {}][prefix :: {}][intent :: {}].", new Object[] { constraint.getType(), field, varPrefix, intend });
        boolean added = true;
        switch(constraint.getType()) {
            case value:
                addValueConstraint(queryString, field, (ValueConstraint) constraint, selectedFields, varPrefix, varNum, intend);
                break;
            case text:
                String var = addFieldGraphPattern(queryString, field, selectedFields, varPrefix, varNum, intend);
                addTextConstraint(queryString, var, (TextConstraint) constraint, endpointType, intend);
                break;
            case range:
                var = addFieldGraphPattern(queryString, field, selectedFields, varPrefix, varNum, intend);
                addRangeConstriant(queryString, var, (RangeConstraint) constraint, intend);
                break;
            default:
                log.warn("Constraint Type '{}' not supported in SPARQL! Constriant {} " + "will be not included in the query!", fieldConstraint.getValue().getType(), fieldConstraint.getValue());
                added = false;
                break;
        }
        if (added) {
            queryString.append(" . \n");
        }
    }
    // rank the graph selected by the query
    if (subSelectState) {
        addRankingConstraints(endpointType, queryString, selectedFields.get(null));
    }
    if (!first) {
        if (subSelectState) {
            queryString.append("    } \n");
            // re-add all selected fields to be added as selects because in
            // the sub-query we only select the ID!
            selectedFields = tmpSelectedFields;
            // ranking needs also to be added to the sub-query (to correctly
            // process LIMIT and OFFSET
            addRankingOrder(endpointType, queryString, selectedFields.get(null), "    ");
            // add LIMIT and OFFSET to the sub-query!
            // TODO: add link to the email
            queryString.append("    ");
            addLimit(query.getLimit(), queryString);
            queryString.append("    ");
            addOffset(query, queryString);
            queryString.append("    ");
        }
        queryString.append("  } \n");
    }
    // if no subqueries are used we need now to add the ranking constraints
    if (!subSelectState) {
        addRankingConstraints(endpointType, queryString, selectedFields.get(null));
    }
    // root variable
    while (selectedFields.size() > 1) {
        // if this is the only left element
        // we are done
        Iterator<String> it = selectedFields.keySet().iterator();
        // we need to get a non null value from the map
        String actField;
        do {
            // the outer while ensures an non null value so we need not to
            // use hasNext
            actField = it.next();
        } while (actField == null);
        queryString.append("  OPTIONAL { ");
        // NOTE the following Method removes the written mapping from the
        // Map
        addFieldGraphPattern(queryString, actField, selectedFields, varPrefix, varNum, "");
        queryString.append(". } \n");
    }
}
Also used : Entry(java.util.Map.Entry) ValueConstraint(org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint) Constraint(org.apache.stanbol.entityhub.servicesapi.query.Constraint) TextConstraint(org.apache.stanbol.entityhub.servicesapi.query.TextConstraint) SimilarityConstraint(org.apache.stanbol.entityhub.servicesapi.query.SimilarityConstraint) RangeConstraint(org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint)

Example 2 with ValueConstraint

use of org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint in project stanbol by apache.

the class BaseGoogleRefineReconcileResource method addPropertyConstraints.

/**
 * @param rQuery
 * @param query
 */
private void addPropertyConstraints(ReconcileQuery rQuery, FieldQuery query) {
    Collection<String> ids = new HashSet<String>();
    // keep order for texts
    List<String> texts = new ArrayList<String>();
    Collection<Object> values = new HashSet<Object>();
    // hold all references for @references special property
    HashSet<String> references = new HashSet<String>();
    // holds all texts for @fullText special property
    List<String> fullText = null;
    // holds the context for the @similarity special property
    Collection<String> similarityContext = null;
    // the field used for the @similarity special property
    HashSet<String> similarityFields = new LinkedHashSet<String>();
    for (Entry<ReconcileProperty, Collection<ReconcileValue>> propertyEntry : rQuery.getProperties()) {
        ReconcileProperty property = propertyEntry.getKey();
        // collect the properties
        for (ReconcileValue value : propertyEntry.getValue()) {
            if (value.getId() != null) {
                ids.add(value.getId());
            }
            if (value.getValue() instanceof String) {
                texts.add((String) value.getValue());
            } else {
                values.add(value.getValue());
            }
        }
        // handle supported special properties
        if (property.isSpecial()) {
            if (property.getName().equalsIgnoreCase("references")) {
                // if Users do parse parameters - so we need to collect all values
                if (property.getParameter() != null) {
                    log.warn("parameters are not supported for @references -> ignore '{}'", property.getParameter());
                }
                if (ids.isEmpty()) {
                    log.warn("No URI values present for parsed @references property! (values: " + propertyEntry.getValue());
                }
                for (String id : ids) {
                    references.add(id);
                }
            } else if (property.getName().equalsIgnoreCase("fulltext")) {
                // if Users do parse parameters - so we need to collect all values
                if (property.getParameter() != null) {
                    log.warn("parameters are not supported for @fullText -> ignore '{}'", property.getParameter());
                }
                fullText = texts;
            } else if (property.getName().equalsIgnoreCase("similarity")) {
                String propUri = property.getParameter() != null ? nsPrefixService.getFullName(property.getParameter()) : SpecialFieldEnum.fullText.getUri();
                if (propUri != null) {
                    similarityFields.add(propUri);
                } else {
                    // TODO: maybe throw an Exception instead
                    log.warn("Unknown prefix '{}' used by Google Refine query parameter of property '{}'! " + "Will use the full text field as fallback", NamespaceMappingUtils.getPrefix(property.getParameter()), property);
                    similarityFields.add(SpecialFieldEnum.fullText.getUri());
                }
                similarityContext = texts;
            } else {
                // TODO: implement LDPATH support
                log.warn("ignore unsupported special property {}", property);
            }
        } else {
            // * non Reference | Text | Datatype values are ignored
            if (!ids.isEmpty()) {
                // only references -> create reference constraint
                query.setConstraint(property.getName(), new ReferenceConstraint(ids));
                if (ids.size() != propertyEntry.getValue().size()) {
                    log.info("Only some of the parsed values of the field {} contain" + "references -> will ignore values with missing references");
                }
            } else if (!texts.isEmpty()) {
                // NOTE: This will use OR over all texts. To enforce AND one
                // would need to parse a single string with all values e.g. by
                // using StringUtils.join(texts," ")
                query.setConstraint(property.getName(), new TextConstraint(texts));
                if (ids.size() != propertyEntry.getValue().size()) {
                    log.info("Only some of the parsed values of the field {} are" + "of type String -> will ignore non-string values");
                }
            } else if (!values.isEmpty()) {
                query.setConstraint(property.getName(), new ValueConstraint(values));
            }
        // else no values ... ignore property
        }
        // clean up
        ids.clear();
        values.clear();
    }
    // now add constraints for the collected special properties
    if (!references.isEmpty()) {
        // add references constraint
        ReferenceConstraint refConstraint = new ReferenceConstraint(references, MODE.all);
        query.setConstraint(SpecialFieldEnum.references.getUri(), refConstraint);
    }
    if (fullText != null && !fullText.isEmpty()) {
        TextConstraint textConstraint = new TextConstraint(fullText);
        query.setConstraint(SpecialFieldEnum.fullText.getUri(), textConstraint);
    // add full text constraint
    }
    if (similarityContext != null && !similarityContext.isEmpty()) {
        // add similarity constraint
        Iterator<String> fieldIt = similarityFields.iterator();
        String field = fieldIt.next();
        SimilarityConstraint simConstraint;
        if (fieldIt.hasNext()) {
            List<String> addFields = new ArrayList<String>(similarityFields.size() - 1);
            while (fieldIt.hasNext()) {
                addFields.add(fieldIt.next());
            }
            simConstraint = new SimilarityConstraint(similarityContext, DataTypeEnum.Text, addFields);
        } else {
            simConstraint = new SimilarityConstraint(similarityContext, DataTypeEnum.Text);
        }
        query.setConstraint(field, simConstraint);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) SimilarityConstraint(org.apache.stanbol.entityhub.servicesapi.query.SimilarityConstraint) ValueConstraint(org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint) ArrayList(java.util.ArrayList) ReconcileProperty(org.apache.stanbol.entityhub.jersey.grefine.ReconcileProperty) ReferenceConstraint(org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint) Collection(java.util.Collection) JSONObject(org.codehaus.jettison.json.JSONObject) TextConstraint(org.apache.stanbol.entityhub.servicesapi.query.TextConstraint) ReconcileValue(org.apache.stanbol.entityhub.jersey.grefine.ReconcileValue) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 3 with ValueConstraint

use of org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint in project stanbol by apache.

the class AbstractBackend method listSubjects.

@Override
public Collection<Object> listSubjects(Object property, Object object) {
    FieldQuery query = createQuery();
    if (this.isURI(object)) {
        query.setConstraint(property.toString(), new ReferenceConstraint(object.toString()));
    } else if (object instanceof Text) {
        Text text = (Text) object;
        TextConstraint constraint;
        if (text.getLanguage() == null) {
            constraint = new TextConstraint(text.getText(), PatternType.none, true);
        } else {
            constraint = new TextConstraint(text.getText(), PatternType.none, true, text.getLanguage());
        }
        query.setConstraint(property.toString(), constraint);
    } else {
        Set<DataTypeEnum> dataTypes = DataTypeEnum.getPrimaryDataTypes(object.getClass());
        if (dataTypes == null || dataTypes.isEmpty()) {
            query.setConstraint(property.toString(), new ValueConstraint(object));
        } else {
            Collection<String> types = new ArrayList<String>(dataTypes.size());
            for (DataTypeEnum type : dataTypes) {
                types.add(type.getUri());
            }
            query.setConstraint(property.toString(), new ValueConstraint(object, types));
        }
    }
    query.setLimit(Integer.valueOf(DEFAULT_MAX_SELECT));
    QueryResultList<String> results;
    try {
        results = query(query);
    } catch (EntityhubException e) {
        throw new IllegalStateException("Unable to query for resources with value '" + object + "' on property '" + property + "'!", e);
    }
    Collection<Object> references;
    if (results.isEmpty()) {
        references = Collections.emptySet();
    } else if (results.size() == 1) {
        // assuming that a single result is a likely case
        references = Collections.singleton((Object) getValueFactory().createReference(results.iterator().next()));
    } else {
        int offset = 0;
        references = new HashSet<Object>(results.size());
        for (String result : results) {
            references.add(getValueFactory().createReference(result));
        }
        while (results.size() >= DEFAULT_MAX_SELECT && references.size() <= DEFAULT_MAX_RESULTS - DEFAULT_MAX_SELECT) {
            offset = offset + results.size();
            query.setOffset(offset);
            try {
                results = query(query);
            } catch (EntityhubException e) {
                throw new IllegalStateException("Unable to query for resources with value '" + object + "' on property '" + property + "'!", e);
            }
            for (String result : results) {
                references.add(getValueFactory().createReference(result));
            }
        }
    }
    return references;
}
Also used : FieldQuery(org.apache.stanbol.entityhub.servicesapi.query.FieldQuery) ValueConstraint(org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint) Text(org.apache.stanbol.entityhub.servicesapi.model.Text) ReferenceConstraint(org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint) DataTypeEnum(org.apache.stanbol.entityhub.servicesapi.defaults.DataTypeEnum) EntityhubException(org.apache.stanbol.entityhub.servicesapi.EntityhubException) TextConstraint(org.apache.stanbol.entityhub.servicesapi.query.TextConstraint)

Example 4 with ValueConstraint

use of org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint in project stanbol by apache.

the class YardTest method testFindMultipleConstraints.

/**
 * Tests simple {@link RangeConstraint}
 */
@Test
public void testFindMultipleConstraints() {
    // init the test data
    FieldQueryTestData data = getFieldQueryTestData();
    // Integer Range and reference query
    FieldQuery query = getYard().getQueryFactory().createFieldQuery();
    // selects r2, r2en, r2de, r5
    query.setConstraint(data.intField, new RangeConstraint(data.intValue2, data.intValue5, true));
    // selects r1, r1en, r1de, r5
    query.setConstraint(data.refField, new ReferenceConstraint(data.refValue1.getReference()));
    query.addSelectedField(data.intField);
    query.addSelectedField(data.refField);
    validateQueryResults(query, getYard().find(query), Arrays.asList(data.r5.getId()), Arrays.asList(data.intField, data.refField));
    // text and reference
    query = getYard().getQueryFactory().createFieldQuery();
    // selects r1en and r2en
    String wildcard = data.textValue1.getText();
    wildcard = wildcard.substring(0, wildcard.length() - 1) + "*";
    query.setConstraint(data.textField, new TextConstraint(wildcard, PatternType.wildcard, false, "en"));
    // selects r1, r1en, r1de, r5
    query.setConstraint(data.refField, new ReferenceConstraint(data.refValue1.getReference()));
    query.addSelectedField(data.refField);
    query.addSelectedField(data.textField);
    validateQueryResults(query, getYard().find(query), Arrays.asList(data.r1en.getId()), Arrays.asList(data.refField, data.textField));
    // text and value
    query = getYard().getQueryFactory().createFieldQuery();
    // selects r1de and r2de
    query.setConstraint(data.textField, new TextConstraint(wildcard, PatternType.wildcard, false, "de"));
    // selects r2, r2en, r2de
    query.setConstraint(data.intField, new ValueConstraint(data.intValue2));
    query.addSelectedField(data.refField);
    query.addSelectedField(data.textField);
    validateQueryResults(query, getYard().find(query), Arrays.asList(data.r2de.getId()), Arrays.asList(data.refField, data.textField));
}
Also used : FieldQuery(org.apache.stanbol.entityhub.servicesapi.query.FieldQuery) RangeConstraint(org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint) ValueConstraint(org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint) ReferenceConstraint(org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint) TextConstraint(org.apache.stanbol.entityhub.servicesapi.query.TextConstraint) Test(org.junit.Test)

Example 5 with ValueConstraint

use of org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint in project stanbol by apache.

the class SolrQueryFactory method initValueConstraint.

/**
 * @param indexConstraint
 * @param refConstraint
 */
private void initValueConstraint(IndexConstraint indexConstraint) {
    ValueConstraint valueConstraint = (ValueConstraint) indexConstraint.getConstraint();
    if (valueConstraint.getValues() == null) {
        indexConstraint.setInvalid(String.format("ValueConstraint without a value - that check only any value for " + "the parsed datatypes %s is present - can not be supported by a Solr query!", valueConstraint.getDataTypes()));
    } else {
        // first process the parsed dataTypes to get the supported types
        List<IndexDataType> indexDataTypes = new ArrayList<IndexDataType>();
        List<String> acceptedDataTypes = new ArrayList<String>();
        if (valueConstraint.getDataTypes() != null) {
            for (String dataType : valueConstraint.getDataTypes()) {
                IndexDataTypeEnum indexDataTypeEnumEntry = IndexDataTypeEnum.forUri(dataType);
                if (indexDataTypeEnumEntry != null) {
                    indexDataTypes.add(indexDataTypeEnumEntry.getIndexType());
                    acceptedDataTypes.add(dataType);
                } else {
                    // TODO: Add possibility to add warnings to indexConstraints
                    log.warn("A Datatype parsed for a ValueConstraint is not " + "supported and will be ignored (dataTypeUri={})", dataType);
                }
            }
        }
        // we support only a single dataType ...
        // ... therefore remove additional data types from the ValueConstraint
        IndexDataType indexDataType = null;
        if (!indexDataTypes.isEmpty()) {
            indexDataType = indexDataTypes.get(0);
            if (indexDataTypes.size() > 1) {
                log.warn("Only a single DataType is supported for ValueConstraints!");
                while (acceptedDataTypes.size() > 1) {
                    String ignored = acceptedDataTypes.remove(acceptedDataTypes.size() - 1);
                    log.warn("  > ignore parsed dataType {}", ignored);
                }
            }
        }
        // else empty we will initialise based on the first parsed value!
        ConstraintValue constraintValue = new ConstraintValue(valueConstraint.getMode());
        // init the boost
        addBoost(constraintValue, valueConstraint);
        for (Object value : valueConstraint.getValues()) {
            IndexValue indexValue;
            if (indexDataType == null) {
                // get the dataType based on the type of the value
                try {
                    indexValue = indexValueFactory.createIndexValue(value);
                } catch (NoConverterException e) {
                    // if not found use the toString() and string as type
                    log.warn("Unable to create IndexValue for value {} (type: {}). Create IndexValue manually by using the first parsed IndexDataType {}", new Object[] { value, value.getClass(), IndexDataTypeEnum.STR.getIndexType() });
                    indexValue = new IndexValue(value.toString(), IndexDataTypeEnum.STR.getIndexType());
                }
                // initialise the IndexDataType for this query based on the first parsed value
                indexDataType = indexValue.getType();
            } else {
                indexValue = new IndexValue(value.toString(), indexDataType);
            }
            // add the constraint
            constraintValue.getValues().add(indexValue);
        }
        // indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.DATATYPE, indexDataType);
        IndexField indexField;
        if (IndexDataTypeEnum.TXT.getIndexType().equals(indexDataType)) {
            // NOTE: in case of TEXT we need also to add the language to create a valid
            // query!
            // * We take the language of the first parsed element
            indexField = new IndexField(indexConstraint.getPath(), indexDataType, constraintValue.getValues().iterator().next().getLanguage());
        } else {
            indexField = new IndexField(indexConstraint.getPath(), indexDataType);
        }
        // set FIELD, DATATYPE and LANGUAGE constraint by using the indexField
        indexConstraint.setIndexFieldConstraints(indexField);
        // set the VALUE
        // TODO: We need to somehow pass the MODE so that the encoder knows how
        // to encode the values
        indexConstraint.setFieldConstraint(IndexConstraintTypeEnum.EQ, constraintValue);
        // update this constraint!
        if (valueConstraint instanceof ReferenceConstraint) {
            indexConstraint.setFieldQueryConstraint(valueConstraint);
        } else {
            indexConstraint.setFieldQueryConstraint(new ValueConstraint(valueConstraint.getValues(), Arrays.asList(indexDataType.getId())));
        }
    }
}
Also used : IndexDataType(org.apache.stanbol.entityhub.yard.solr.model.IndexDataType) ValueConstraint(org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint) ArrayList(java.util.ArrayList) IndexValue(org.apache.stanbol.entityhub.yard.solr.model.IndexValue) ReferenceConstraint(org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint) NoConverterException(org.apache.stanbol.entityhub.yard.solr.model.NoConverterException) IndexDataTypeEnum(org.apache.stanbol.entityhub.yard.solr.defaults.IndexDataTypeEnum) IndexField(org.apache.stanbol.entityhub.yard.solr.model.IndexField)

Aggregations

ValueConstraint (org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint)11 TextConstraint (org.apache.stanbol.entityhub.servicesapi.query.TextConstraint)9 ReferenceConstraint (org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint)7 RangeConstraint (org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint)5 SimilarityConstraint (org.apache.stanbol.entityhub.servicesapi.query.SimilarityConstraint)5 Constraint (org.apache.stanbol.entityhub.servicesapi.query.Constraint)4 JSONObject (org.codehaus.jettison.json.JSONObject)4 ArrayList (java.util.ArrayList)3 DataTypeEnum (org.apache.stanbol.entityhub.servicesapi.defaults.DataTypeEnum)3 FieldQuery (org.apache.stanbol.entityhub.servicesapi.query.FieldQuery)3 JSONArray (org.codehaus.jettison.json.JSONArray)3 HashSet (java.util.HashSet)2 MODE (org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint.MODE)2 Test (org.junit.Test)2 Collection (java.util.Collection)1 LinkedHashSet (java.util.LinkedHashSet)1 Entry (java.util.Map.Entry)1 ReconcileProperty (org.apache.stanbol.entityhub.jersey.grefine.ReconcileProperty)1 ReconcileValue (org.apache.stanbol.entityhub.jersey.grefine.ReconcileValue)1 EntityhubException (org.apache.stanbol.entityhub.servicesapi.EntityhubException)1