lucenequerybuilder.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 986 行 · 第 1/3 页
JAVA
986 行
} QueryParser parser = new QueryParser(fieldname, analyzer); parser.setOperator(QueryParser.DEFAULT_OPERATOR_AND); // replace escaped ' with just ' StringBuffer query = new StringBuffer(); String textsearch = node.getQuery(); // the default lucene query parser recognizes 'AND' and 'NOT' as // keywords. textsearch = textsearch.replaceAll("AND", "and"); textsearch = textsearch.replaceAll("NOT", "not"); boolean escaped = false; for (int i = 0; i < textsearch.length(); i++) { if (textsearch.charAt(i) == '\\') { if (escaped) { query.append("\\\\"); escaped = false; } else { escaped = true; } } else if (textsearch.charAt(i) == '\'') { if (escaped) { escaped = false; } query.append(textsearch.charAt(i)); } else { if (escaped) { query.append('\\'); escaped = false; } query.append(textsearch.charAt(i)); } } Query context = parser.parse(query.toString()); if (relPath != null && (!node.getReferencesProperty() || relPath.getLength() > 1)) { // text search on some child axis Path.PathElement[] elements = relPath.getElements(); for (int i = elements.length - 1; i >= 0; i--) { String name = null; if (!elements[i].getName().equals(RelationQueryNode.STAR_NAME_TEST)) { name = NameFormat.format(elements[i].getName(), nsMappings);; } // join text search with name test // if path references property that's elements.length - 2 // if path references node that's elements.length - 1 if (name != null && ((node.getReferencesProperty() && i == elements.length - 2) || (!node.getReferencesProperty() && i == elements.length - 1))) { Query q = new TermQuery(new Term(FieldNames.LABEL, name)); BooleanQuery and = new BooleanQuery(); and.add(q, Occur.MUST); and.add(context, Occur.MUST); context = and; } else if ((node.getReferencesProperty() && i < elements.length - 2) || (!node.getReferencesProperty() && i < elements.length - 1)) { // otherwise do a parent axis step context = new ParentAxisQuery(context, name); } } // finally select parent context = new ParentAxisQuery(context, null); } return context; } catch (NamespaceException e) { exceptions.add(e); } catch (ParseException e) { exceptions.add(e); } catch (NoPrefixDeclaredException e) { exceptions.add(e); } return null; } public Object visit(PathQueryNode node, Object data) { Query context = null; LocationStepQueryNode[] steps = node.getPathSteps(); if (steps.length > 0) { if (node.isAbsolute() && !steps[0].getIncludeDescendants()) { // eat up first step QName nameTest = steps[0].getNameTest(); if (nameTest == null) { // this is equivalent to the root node context = new TermQuery(new Term(FieldNames.PARENT, "")); } else if (nameTest.getLocalName().length() == 0) { // root node context = new TermQuery(new Term(FieldNames.PARENT, "")); } else { // then this is a node != the root node // will never match anything! String name = ""; try { name = NameFormat.format(nameTest, nsMappings); } catch (NoPrefixDeclaredException e) { exceptions.add(e); } BooleanQuery and = new BooleanQuery(); and.add(new TermQuery(new Term(FieldNames.PARENT, "")), Occur.MUST); and.add(new TermQuery(new Term(FieldNames.LABEL, name)), Occur.MUST); context = and; } LocationStepQueryNode[] tmp = new LocationStepQueryNode[steps.length - 1]; System.arraycopy(steps, 1, tmp, 0, steps.length - 1); steps = tmp; } else { // path is 1) relative or 2) descendant-or-self // use root node as context context = new TermQuery(new Term(FieldNames.PARENT, "")); } } else { exceptions.add(new InvalidQueryException("Number of location steps must be > 0")); } // loop over steps for (int i = 0; i < steps.length; i++) { context = (Query) steps[i].accept(this, context); } if (data instanceof BooleanQuery) { BooleanQuery constraint = (BooleanQuery) data; if (constraint.getClauses().length > 0) { constraint.add(context, Occur.MUST); context = constraint; } } return context; } public Object visit(LocationStepQueryNode node, Object data) { Query context = (Query) data; BooleanQuery andQuery = new BooleanQuery(); if (context == null) { exceptions.add(new IllegalArgumentException("Unsupported query")); } // predicate on step? Object[] predicates = node.acceptOperands(this, data); for (int i = 0; i < predicates.length; i++) { andQuery.add((Query) predicates[i], Occur.MUST); } // check for position predicate QueryNode[] pred = node.getPredicates(); for (int i = 0; i < pred.length; i++) { if (pred[i].getType() == QueryNode.TYPE_RELATION) { RelationQueryNode pos = (RelationQueryNode) pred[i]; if (pos.getValueType() == QueryConstants.TYPE_POSITION) { node.setIndex(pos.getPositionValue()); } } } TermQuery nameTest = null; if (node.getNameTest() != null) { try { String internalName = NameFormat.format(node.getNameTest(), nsMappings); nameTest = new TermQuery(new Term(FieldNames.LABEL, internalName)); } catch (NoPrefixDeclaredException e) { // should never happen exceptions.add(e); } } if (node.getIncludeDescendants()) { if (nameTest != null) { andQuery.add(new DescendantSelfAxisQuery(context, nameTest), Occur.MUST); } else { // descendant-or-self with nametest=* if (predicates.length > 0) { // if we have a predicate attached, the condition acts as // the sub query. // only use descendant axis if path is not //* // otherwise the query for the predicate can be used itself PathQueryNode pathNode = (PathQueryNode) node.getParent(); if (pathNode.getPathSteps()[0] != node) { Query subQuery = new DescendantSelfAxisQuery(context, andQuery, false); andQuery = new BooleanQuery(); andQuery.add(subQuery, Occur.MUST); } } else { // todo this will traverse the whole index, optimize! Query subQuery = null; try { subQuery = new MatchAllQuery(NameFormat.format(QName.JCR_PRIMARYTYPE, nsMappings)); } catch (NoPrefixDeclaredException e) { // will never happen, prefixes are created when unknown } // only use descendant axis if path is not //* PathQueryNode pathNode = (PathQueryNode) node.getParent(); if (pathNode.getPathSteps()[0] != node) { context = new DescendantSelfAxisQuery(context, subQuery); andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex()), Occur.MUST); } else { andQuery.add(subQuery, Occur.MUST); } } } } else { // name test if (nameTest != null) { andQuery.add(new ChildAxisQuery(sharedItemMgr, context, nameTest.getTerm().text(), node.getIndex()), Occur.MUST); } else { // select child nodes andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex()), Occur.MUST); } } return andQuery; } public Object visit(DerefQueryNode node, Object data) { Query context = (Query) data; if (context == null) { exceptions.add(new IllegalArgumentException("Unsupported query")); } try { String refProperty = NameFormat.format(node.getRefProperty(), nsMappings); String nameTest = null; if (node.getNameTest() != null) { nameTest = NameFormat.format(node.getNameTest(), nsMappings); } if (node.getIncludeDescendants()) { Query refPropQuery = new MatchAllQuery(refProperty); context = new DescendantSelfAxisQuery(context, refPropQuery, false); } context = new DerefQuery(context, refProperty, nameTest); // attach predicates Object[] predicates = node.acceptOperands(this, data); if (predicates.length > 0) { BooleanQuery andQuery = new BooleanQuery(); for (int i = 0; i < predicates.length; i++) { andQuery.add((Query) predicates[i], Occur.MUST); } andQuery.add(context, Occur.MUST); context = andQuery; } } catch (NoPrefixDeclaredException e) { // should never happen exceptions.add(e); } return context; } public Object visit(RelationQueryNode node, Object data) { Query query; String[] stringValues = new String[1]; switch (node.getValueType()) { case 0: // not set: either IS NULL or IS NOT NULL break; case QueryConstants.TYPE_DATE: stringValues[0] = DateField.dateToString(node.getDateValue()); break; case QueryConstants.TYPE_DOUBLE: stringValues[0] = DoubleField.doubleToString(node.getDoubleValue()); break; case QueryConstants.TYPE_LONG: stringValues[0] = LongField.longToString(node.getLongValue()); break; case QueryConstants.TYPE_STRING: if (node.getOperation() == QueryConstants.OPERATION_EQ_GENERAL || node.getOperation() == QueryConstants.OPERATION_EQ_VALUE || node.getOperation() == QueryConstants.OPERATION_NE_GENERAL || node.getOperation() == QueryConstants.OPERATION_NE_VALUE) { // only use coercing on non-range operations QName propertyName = node.getRelativePath().getNameElement().getName(); stringValues = getStringValues(propertyName, node.getStringValue()); } else { stringValues[0] = node.getStringValue(); } break; case QueryConstants.TYPE_POSITION: // ignore position. is handled in the location step return null; default: throw new IllegalArgumentException("Unknown relation type: " + node.getValueType()); } if (node.getRelativePath() == null) { exceptions.add(new InvalidQueryException("@* not supported in predicate")); return data; } // get property transformation final int[] transform = new int[]{TransformConstants.TRANSFORM_NONE}; node.acceptOperands(new DefaultQueryNodeVisitor() { public Object visit(PropertyFunctionQueryNode node, Object data) { if (node.getFunctionName().equals(PropertyFunctionQueryNode.LOWER_CASE)) { transform[0] = TransformConstants.TRANSFORM_LOWER_CASE; } else if (node.getFunctionName().equals(PropertyFunctionQueryNode.UPPER_CASE)) { transform[0] = TransformConstants.TRANSFORM_UPPER_CASE; } return data; } }, null); Path relPath = node.getRelativePath(); String field = ""; try { field = NameFormat.format(relPath.getNameElement().getName(), nsMappings); } catch (NoPrefixDeclaredException e) { // should never happen exceptions.add(e); } switch (node.getOperation()) { case QueryConstants.OPERATION_EQ_VALUE: // = case QueryConstants.OPERATION_EQ_GENERAL: BooleanQuery or = new BooleanQuery(); 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); } or.add(q, Occur.SHOULD); } query = or; if (node.getOperation() == QueryConstants.OPERATION_EQ_VALUE) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?