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 + -
显示快捷键?