Search in sources :

Example 1 with IndexValue

use of org.apache.stanbol.entityhub.yard.solr.model.IndexValue in project stanbol by apache.

the class SolrQueryFactory method parseFieldQuery.

/**
     * Converts the field query to a SolrQuery. In addition changes the parsed
     * FieldQuery (e.g. removing unsupported features, setting defaults for
     * missing parameters)
     * @param fieldQuery the field query (will be modified to reflect the query
     * as executed)
     * @param select the SELECT mode
     * @return the SolrQuery
     */
public SolrQuery parseFieldQuery(FieldQuery fieldQuery, SELECT select) {
    SolrQuery query = initSolrQuery(fieldQuery);
    setSelected(query, fieldQuery, select);
    StringBuilder queryString = new StringBuilder();
    Map<String, Constraint> processedFieldConstraints = new HashMap<String, Constraint>();
    boolean firstConstraint = true;
    boolean similarityConstraintPresent = false;
    for (Entry<String, Constraint> fieldConstraint : fieldQuery) {
        if (fieldConstraint.getValue().getType() == ConstraintType.similarity) {
            // TODO: log make the FieldQuery ensure that there is no more than one instead of similarity
            // constraint per query
            List<String> fields = new ArrayList<String>();
            fields.add(fieldConstraint.getKey());
            SimilarityConstraint simConstraint = (SimilarityConstraint) fieldConstraint.getValue();
            final IndexValue contextValue = indexValueFactory.createIndexValue(simConstraint.getContext());
            fields.addAll(simConstraint.getAdditionalFields());
            if (!similarityConstraintPresent) {
                //similarity constraint present
                similarityConstraintPresent = true;
                //add the constraint to the query
                query.setRequestHandler(MLT_QUERY_TYPE);
                query.set(MATCH_INCLUDE, false);
                query.set(MIN_DOC_FREQ, 1);
                query.set(MIN_TERM_FREQ, 1);
                query.set(INTERESTING_TERMS, "details");
                //testing
                query.set("mlt.boost", true);
                List<String> indexFields = new ArrayList<String>();
                for (String field : fields) {
                    //we need to get the actual fields in the index for the
                    //logical fields parsed with the constraint
                    IndexDataTypeEnum mapedIndexTypeEnum = IndexDataTypeEnum.forDataTyoe(simConstraint.getContextType());
                    IndexField indexField = new IndexField(Collections.singletonList(field), mapedIndexTypeEnum == null ? null : mapedIndexTypeEnum.getIndexType(), simConstraint.getLanguages());
                    indexFields.addAll(fieldMapper.getQueryFieldNames(indexField));
                }
                query.set(SIMILARITY_FIELDS, indexFields.toArray(new String[fields.size()]));
                query.set(STREAM_BODY, contextValue.getValue());
                processedFieldConstraints.put(fieldConstraint.getKey(), fieldConstraint.getValue());
            } else {
                //similarity constraint already present -> ignore further
                //NOTE: users are informed about that by NOT including further
                //      similarity constraints in the query included in the
                //      response
                log.warn("The parsed FieldQuery contains multiple Similarity constraints." + "However only a single one can be supported per query. Because of " + "this all further Similarity constraints will be ignored!");
                log.warn("Ignore SimilarityConstraint:");
                log.warn(" > Field      : {}", fieldConstraint.getKey());
                log.warn(" > Context    : {}", simConstraint.getContext());
                log.warn(" > Add Fields : {}", simConstraint.getAdditionalFields());
            }
        } else {
            IndexConstraint indexConstraint = createIndexConstraint(fieldConstraint);
            if (indexConstraint.isInvalid()) {
                log.warn("Unable to create IndexConstraint for Constraint {} (type: {}) and Field {} (Reosens: {})", new Object[] { fieldConstraint.getValue(), fieldConstraint.getValue().getType(), fieldConstraint.getKey(), indexConstraint.getInvalidMessages() });
            } else {
                if (firstConstraint) {
                    queryString.append('(');
                    firstConstraint = false;
                } else {
                    queryString.append(") AND (");
                }
                indexConstraint.encode(queryString);
                //set the constraint (may be changed because of some unsupported features)
                processedFieldConstraints.put(fieldConstraint.getKey(), //if null
                indexConstraint.getFieldQueryConstraint() == null ? //assume no change and add the parsed one
                fieldConstraint.getValue() : //add the changed version
                indexConstraint.getFieldQueryConstraint());
            }
        }
    }
    if (!firstConstraint) {
        queryString.append(')');
    }
    //set the constraints as processed to the parsed query
    fieldQuery.removeAllConstraints();
    for (Entry<String, Constraint> constraint : processedFieldConstraints.entrySet()) {
        fieldQuery.setConstraint(constraint.getKey(), constraint.getValue());
    }
    if (queryString.length() > 0) {
        String qs = queryString.toString();
        log.debug("QueryString: {}", qs);
        if (MLT_QUERY_TYPE.equals(query.getRequestHandler())) {
            query.set(CommonParams.FQ, qs);
        } else {
            query.setQuery(qs);
        }
    }
    log.debug("Solr Query: {}", query);
    return query;
}
Also used : SimilarityConstraint(org.apache.stanbol.entityhub.servicesapi.query.SimilarityConstraint) HashMap(java.util.HashMap) ReferenceConstraint(org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint) SimilarityConstraint(org.apache.stanbol.entityhub.servicesapi.query.SimilarityConstraint) RangeConstraint(org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint) ValueConstraint(org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint) Constraint(org.apache.stanbol.entityhub.servicesapi.query.Constraint) TextConstraint(org.apache.stanbol.entityhub.servicesapi.query.TextConstraint) ArrayList(java.util.ArrayList) IndexValue(org.apache.stanbol.entityhub.yard.solr.model.IndexValue) SolrQuery(org.apache.solr.client.solrj.SolrQuery) IndexDataTypeEnum(org.apache.stanbol.entityhub.yard.solr.defaults.IndexDataTypeEnum) IndexField(org.apache.stanbol.entityhub.yard.solr.model.IndexField)

Example 2 with IndexValue

use of org.apache.stanbol.entityhub.yard.solr.model.IndexValue 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)

Example 3 with IndexValue

use of org.apache.stanbol.entityhub.yard.solr.model.IndexValue in project stanbol by apache.

the class WildcardEncoder method encode.

@Override
public void encode(EncodedConstraintParts constraint, ConstraintValue value) {
    if (value == null || value.getValues().isEmpty()) {
        throw new IllegalArgumentException("This encoder does not support the NULL IndexValue!");
    }
    // encode the value based on the type
    Set<String> queryConstraints = new HashSet<String>();
    //the query constraints used for the phrase constraint
    Collection<String> phraseTerms = new ArrayList<String>();
    for (IndexValue indexValue : value) {
        if (indexValue != null) {
            if (!SUPPORTED_TYPES.contains(indexValue.getType())) {
                throw new IllegalArgumentException(String.format("This encoder does not support the IndexDataType %s (supported: %s)", indexValue.getType(), SUPPORTED_TYPES));
            } else {
                for (QueryTerm qt : QueryUtils.encodeQueryValue(indexValue, false)) {
                    StringBuilder sb = new StringBuilder(qt.needsQuotes ? qt.term.length() + 2 : 0);
                    if (qt.needsQuotes) {
                        sb.append('"').append(qt.term).append('"');
                        queryConstraints.add(sb.toString());
                    } else {
                        queryConstraints.add(qt.term);
                    }
                    if (value.getBoost() != null) {
                        sb.append("^").append(value.getBoost());
                    }
                    if (!qt.hasWildcard && qt.isText) {
                        //phrases do not work with wildcard and are only
                        //relevant for texts
                        phraseTerms.add(qt.term);
                    }
                }
            }
            if (value.getMode() == MODE.any) {
                //in any mode
                //we need to add constraints separately (to connect them with OR)
                constraint.addEncoded(POS, queryConstraints);
                queryConstraints.clear();
            }
        }
    // else ignore null value
    }
    if (value.getMode() == MODE.all) {
        // an all mode we need to add all
        //constraint in a single call (to connect them with AND)
        constraint.addEncoded(POS, queryConstraints);
    } else {
        if (phraseTerms.size() > 1) {
            Boolean state = (Boolean) value.getProperty(QueryConst.PHRASE_QUERY_STATE);
            if (state != null && state.booleanValue()) {
                StringBuilder sb = encodePhraseQuery(phraseTerms);
                if (value.getBoost() != null) {
                    sb.append("^").append(value.getBoost());
                }
                constraint.addEncoded(POS, sb.toString());
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) QueryTerm(org.apache.stanbol.entityhub.yard.solr.query.QueryUtils.QueryTerm) IndexValue(org.apache.stanbol.entityhub.yard.solr.model.IndexValue) HashSet(java.util.HashSet)

Example 4 with IndexValue

use of org.apache.stanbol.entityhub.yard.solr.model.IndexValue in project stanbol by apache.

the class LeEncoder method encode.

@Override
public void encode(EncodedConstraintParts constraint, Object value) {
    IndexValue indexValue;
    Double boost = null;
    if (value == null) {
        // default value
        indexValue = null;
    } else if (value instanceof IndexValue) {
        indexValue = (IndexValue) value;
    } else if (value instanceof ConstraintValue) {
        ConstraintValue cv = (ConstraintValue) value;
        indexValue = cv.getValues() == null || cv.getValues().isEmpty() ? null : cv.getValues().iterator().next();
        boost = cv.getBoost();
    } else {
        indexValue = indexValueFactory.createIndexValue(value);
    }
    StringBuilder leConstraint = new StringBuilder("TO ");
    if (indexValue != null && indexValue.getValue() != null && !indexValue.getValue().isEmpty()) {
        leConstraint.append(indexValue.getValue());
    } else {
        leConstraint.append(DEFAULT);
    }
    leConstraint.append(']');
    if (boost != null) {
        leConstraint.append("^").append(boost);
    }
    constraint.addEncoded(POS, leConstraint.toString());
}
Also used : IndexValue(org.apache.stanbol.entityhub.yard.solr.model.IndexValue) ConstraintValue(org.apache.stanbol.entityhub.yard.solr.impl.SolrQueryFactory.ConstraintValue)

Example 5 with IndexValue

use of org.apache.stanbol.entityhub.yard.solr.model.IndexValue in project stanbol by apache.

the class RegexEncoder method encode.

@Override
public void encode(EncodedConstraintParts constraint, ConstraintValue value) {
    if (value == null || value.getValues().isEmpty()) {
        throw new IllegalArgumentException("This encoder does not support the NULL IndexValue!");
    }
    // encode the value based on the type
    Set<String> queryConstraints = new HashSet<String>();
    for (IndexValue indexValue : value) {
        if (value != null) {
            if (!SUPPORTED_TYPES.contains(indexValue.getType())) {
                throw new IllegalArgumentException(String.format("This encoder does not support the IndexDataType %s (supported: %s)", indexValue.getType(), SUPPORTED_TYPES));
            } else {
                // NOTE that not all regex queries can be supported by Solr
                // see https://issues.apache.org/jira/browse/LUCENE-2604
                StringBuilder sb = new StringBuilder(indexValue.getValue().length() + 2);
                sb.append('/').append(indexValue.getValue()).append('/');
                if (value.getBoost() != null) {
                    sb.append('^').append(value.getBoost());
                }
                queryConstraints.add(sb.toString());
            }
            if (value.getMode() == MODE.any) {
                //in any mode
                //we need to add constraints separately (to connect them with OR)
                constraint.addEncoded(POS, queryConstraints);
                queryConstraints.clear();
            }
        }
    //else ignore null element
    }
    if (value.getMode() == MODE.all) {
        // an all mode we need to add all
        //constraint in a single call (to connect them with AND)
        constraint.addEncoded(POS, queryConstraints);
    }
}
Also used : IndexValue(org.apache.stanbol.entityhub.yard.solr.model.IndexValue) HashSet(java.util.HashSet)

Aggregations

IndexValue (org.apache.stanbol.entityhub.yard.solr.model.IndexValue)11 ArrayList (java.util.ArrayList)4 ConstraintValue (org.apache.stanbol.entityhub.yard.solr.impl.SolrQueryFactory.ConstraintValue)4 HashSet (java.util.HashSet)3 IndexField (org.apache.stanbol.entityhub.yard.solr.model.IndexField)3 RangeConstraint (org.apache.stanbol.entityhub.servicesapi.query.RangeConstraint)2 ReferenceConstraint (org.apache.stanbol.entityhub.servicesapi.query.ReferenceConstraint)2 ValueConstraint (org.apache.stanbol.entityhub.servicesapi.query.ValueConstraint)2 IndexDataTypeEnum (org.apache.stanbol.entityhub.yard.solr.defaults.IndexDataTypeEnum)2 IndexDataType (org.apache.stanbol.entityhub.yard.solr.model.IndexDataType)2 NoConverterException (org.apache.stanbol.entityhub.yard.solr.model.NoConverterException)2 QueryTerm (org.apache.stanbol.entityhub.yard.solr.query.QueryUtils.QueryTerm)2 HashMap (java.util.HashMap)1 SolrQuery (org.apache.solr.client.solrj.SolrQuery)1 SolrInputDocument (org.apache.solr.common.SolrInputDocument)1 SolrInputField (org.apache.solr.common.SolrInputField)1 Constraint (org.apache.stanbol.entityhub.servicesapi.query.Constraint)1 SimilarityConstraint (org.apache.stanbol.entityhub.servicesapi.query.SimilarityConstraint)1 TextConstraint (org.apache.stanbol.entityhub.servicesapi.query.TextConstraint)1