lucenequerybuilder.java

来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 986 行 · 第 1/3 页

JAVA
986
字号
                    query = createSingleValueConstraint(or, field);                }                break;            case QueryConstants.OPERATION_GE_VALUE:      // >=            case QueryConstants.OPERATION_GE_GENERAL:                or = new BooleanQuery();                for (int i = 0; i < stringValues.length; i++) {                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, "\uFFFF"));                    or.add(new RangeQuery(lower, upper, true, transform[0]), Occur.SHOULD);                }                query = or;                if (node.getOperation() == QueryConstants.OPERATION_GE_VALUE) {                    query = createSingleValueConstraint(or, field);                }                break;            case QueryConstants.OPERATION_GT_VALUE:      // >            case QueryConstants.OPERATION_GT_GENERAL:                or = new BooleanQuery();                for (int i = 0; i < stringValues.length; i++) {                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, "\uFFFF"));                    or.add(new RangeQuery(lower, upper, false, transform[0]), Occur.SHOULD);                }                query = or;                if (node.getOperation() == QueryConstants.OPERATION_GT_VALUE) {                    query = createSingleValueConstraint(or, field);                }                break;            case QueryConstants.OPERATION_LE_VALUE:      // <=            case QueryConstants.OPERATION_LE_GENERAL:      // <=                or = new BooleanQuery();                for (int i = 0; i < stringValues.length; i++) {                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, ""));                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));                    or.add(new RangeQuery(lower, upper, true, transform[0]), Occur.SHOULD);                }                query = or;                if (node.getOperation() == QueryConstants.OPERATION_LE_VALUE) {                    query = createSingleValueConstraint(query, field);                }                break;            case QueryConstants.OPERATION_LIKE:          // LIKE                // the like operation always has one string value.                // no coercing, see above                if (stringValues[0].equals("%")) {                    query = new MatchAllQuery(field);                } else {                    query = new WildcardQuery(FieldNames.PROPERTIES, field, stringValues[0], transform[0]);                }                break;            case QueryConstants.OPERATION_LT_VALUE:      // <            case QueryConstants.OPERATION_LT_GENERAL:                or = new BooleanQuery();                for (int i = 0; i < stringValues.length; i++) {                    Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, ""));                    Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));                    or.add(new RangeQuery(lower, upper, false, transform[0]), Occur.SHOULD);                }                query = or;                if (node.getOperation() == QueryConstants.OPERATION_LT_VALUE) {                    query = createSingleValueConstraint(or, field);                }                break;            case QueryConstants.OPERATION_NE_VALUE:      // !=                // match nodes with property 'field' that includes svp and mvp                BooleanQuery notQuery = new BooleanQuery();                notQuery.add(new MatchAllQuery(field), Occur.SHOULD);                // exclude all nodes where 'field' has the term in question                for (int i = 0; i < stringValues.length; i++) {                    Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));                    Query q;                    if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {                        q = new CaseTermQuery.Upper(t);                    } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {                        q = new CaseTermQuery.Lower(t);                    } else {                        q = new TermQuery(t);                    }                    notQuery.add(q, Occur.MUST_NOT);                }                // and exclude all nodes where 'field' is multi valued                notQuery.add(new TermQuery(new Term(FieldNames.MVP, field)), Occur.MUST_NOT);                query = notQuery;                break;            case QueryConstants.OPERATION_NE_GENERAL:    // !=                // that's:                // all nodes with property 'field'                // minus the nodes that have a single property 'field' that is                //    not equal to term in question                // minus the nodes that have a multi-valued property 'field' and                //    all values are equal to term in question                notQuery = new BooleanQuery();                notQuery.add(new MatchAllQuery(field), Occur.SHOULD);                for (int i = 0; i < stringValues.length; i++) {                    // exclude the nodes that have the term and are single valued                    Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));                    Query svp = new NotQuery(new TermQuery(new Term(FieldNames.MVP, field)));                    BooleanQuery and = new BooleanQuery();                    Query q;                    if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {                        q = new CaseTermQuery.Upper(t);                    } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {                        q = new CaseTermQuery.Lower(t);                    } else {                        q = new TermQuery(t);                    }                    and.add(q, Occur.MUST);                    and.add(svp, Occur.MUST);                    notQuery.add(and, Occur.MUST_NOT);                }                // todo above also excludes multi-valued properties that contain                //      multiple instances of only stringValues. e.g. text={foo, foo}                query = notQuery;                break;            case QueryConstants.OPERATION_NULL:                query = new NotQuery(new MatchAllQuery(field));                break;            case QueryConstants.OPERATION_NOT_NULL:                query = new MatchAllQuery(field);                break;            default:                throw new IllegalArgumentException("Unknown relation operation: "                        + node.getOperation());        }        if (relPath.getLength() > 1) {            try {                // child axis in relation                Path.PathElement[] elements = relPath.getElements();                // elements.length - 1 = property name                // elements.length - 2 = last child axis name test                for (int i = elements.length - 2; i >= 0; i--) {                    String name = null;                    if (!elements[i].getName().equals(RelationQueryNode.STAR_NAME_TEST)) {                        name = NameFormat.format(elements[i].getName(), nsMappings);                    }                    if (i == elements.length - 2) {                        // join name test with property query if there is one                        if (name != null) {                            Query nameTest = new TermQuery(new Term(FieldNames.LABEL, name));                            BooleanQuery and = new BooleanQuery();                            and.add(query, Occur.MUST);                            and.add(nameTest, Occur.MUST);                            query = and;                        } else {                            // otherwise the query can be used as is                        }                    } else {                        query = new ParentAxisQuery(query, name);                    }                }            } catch (NoPrefixDeclaredException e) {                // should never happen                exceptions.add(e);            }            // finally select the parent of the selected nodes            query = new ParentAxisQuery(query, null);        }        return query;    }    public Object visit(OrderQueryNode node, Object data) {        return data;    }    public Object visit(PropertyFunctionQueryNode node, Object data) {        return data;    }    //---------------------------< internal >-----------------------------------    /**     * Wraps a constraint query around <code>q</code> that limits the nodes to     * those where <code>propName</code> is the name of a single value property     * on the node instance.     *     * @param q        the query to wrap.     * @param propName the name of a property that only has one value.     * @return the wrapped query <code>q</code>.     */    private Query createSingleValueConstraint(Query q, String propName) {        // get nodes with multi-values in propName        Query mvp = new TermQuery(new Term(FieldNames.MVP, propName));        // now negate, that gives the nodes that have propName as single        // values but also all others        Query svp = new NotQuery(mvp);        // now join the two, which will result in those nodes where propName        // only contains a single value. This works because q already restricts        // the result to those nodes that have a property propName        BooleanQuery and = new BooleanQuery();        and.add(q, Occur.MUST);        and.add(svp, Occur.MUST);        return and;    }    /**     * Returns an array of String values to be used as a term to lookup the search index     * for a String <code>literal</code> of a certain property name. This method     * will lookup the <code>propertyName</code> in the node type registry     * trying to find out the {@link javax.jcr.PropertyType}s.     * If no property type is found looking up node type information, this     * method will guess the property type.     *     * @param propertyName the name of the property in the relation.     * @param literal      the String literal in the relation.     * @return the String values to use as term for the query.     */    private String[] getStringValues(QName propertyName, String literal) {        PropertyTypeRegistry.TypeMapping[] types = propRegistry.getPropertyTypes(propertyName);        List values = new ArrayList();        for (int i = 0; i < types.length; i++) {            switch (types[i].type) {                case PropertyType.NAME:                    // try to translate name                    try {                        values.add(nsMappings.translatePropertyName(literal, session.getNamespaceResolver()));                        log.debug("Coerced " + literal + " into NAME.");                    } catch (NameException e) {                        log.warn("Unable to coerce '" + literal + "' into a NAME: " + e.toString());                    }                    break;                case PropertyType.PATH:                    // try to translate path                    try {                        Path p = session.getQPath(literal);                        values.add(PathFormat.format(p, nsMappings));                        log.debug("Coerced " + literal + " into PATH.");                    } catch (NameException e) {                        log.warn("Unable to coerce '" + literal + "' into a PATH: " + e.toString());                    } catch (NamespaceException e) {                        log.warn("Unable to coerce '" + literal + "' into a PATH: " + e.toString());                    }                    break;                case PropertyType.DATE:                    // try to parse date                    Calendar c = ISO8601.parse(literal);                    if (c != null) {                        values.add(DateField.timeToString(c.getTimeInMillis()));                        log.debug("Coerced " + literal + " into DATE.");                    } else {                        log.warn("Unable to coerce '" + literal + "' into a DATE.");                    }                    break;                case PropertyType.DOUBLE:                    // try to parse double                    try {                        double d = Double.parseDouble(literal);                        values.add(DoubleField.doubleToString(d));                        log.debug("Coerced " + literal + " into DOUBLE.");                    } catch (NumberFormatException e) {                        log.warn("Unable to coerce '" + literal + "' into a DOUBLE: " + e.toString());                    }                    break;                case PropertyType.LONG:                    // try to parse long                    try {                        long l = Long.parseLong(literal);                        values.add(LongField.longToString(l));                        log.debug("Coerced " + literal + " into LONG.");                    } catch (NumberFormatException e) {                        log.warn("Unable to coerce '" + literal + "' into a LONG: " + e.toString());                    }                    break;                case PropertyType.STRING:                    values.add(literal);                    log.debug("Using literal " + literal + " as is.");                    break;            }        }        if (values.size() == 0) {            // use literal as is then try to guess other types            values.add(literal);            // try to guess property type            if (literal.indexOf('/') > -1) {                // might be a path                try {                    values.add(PathFormat.format(                            session.getQPath(literal), nsMappings));                    log.debug("Coerced " + literal + " into PATH.");                } catch (Exception e) {                    // not a path                }            }            if (XMLChar.isValidName(literal)) {                // might be a name                try {                    values.add(nsMappings.translatePropertyName(literal, session.getNamespaceResolver()));                    log.debug("Coerced " + literal + " into NAME.");                } catch (Exception e) {                    // not a name                }            }            if (literal.indexOf(':') > -1) {                // is it a date?                Calendar c = ISO8601.parse(literal);                if (c != null) {                    values.add(DateField.timeToString(c.getTimeInMillis()));                    log.debug("Coerced " + literal + " into DATE.");                }            } else {                // long or double are possible at this point                try {                    values.add(LongField.longToString(Long.parseLong(literal)));                    log.debug("Coerced " + literal + " into LONG.");                } catch (NumberFormatException e) {                    // not a long                    // try double                    try {                        values.add(DoubleField.doubleToString(Double.parseDouble(literal)));                        log.debug("Coerced " + literal + " into DOUBLE.");                    } catch (NumberFormatException e1) {                        // not a double                    }                }            }        }        // if still no values use literal as is        if (values.size() == 0) {            values.add(literal);            log.debug("Using literal " + literal + " as is.");        }        return (String[]) values.toArray(new String[values.size()]);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?