private TwigQuery rewriteClauses(TwigQuery clone, final IndexReader reader) throws IOException { for (int i = 0 ; i < clauses.size(); i++) { final NodeBooleanClause c = clauses.get(i); final NodeQuery query = (NodeQuery) c.getQuery().rewrite(reader); if (query != c.getQuery()) { // clause rewrote: must clone if (clone == null) { clone = (TwigQuery) this.clone(); // clone and set root since clone is null, i.e., root has not been rewritten clone.root = (NodeQuery) this.root.clone(); // copy ancestor clone.root.setAncestorPointer(ancestor); } // set root as ancestor query.setAncestorPointer(clone.root); clone.clauses.set(i, new NodeBooleanClause(query, c.getOccur())); } } return clone; }
/** Prints a user-readable version of this query. */ @Override public String toString(final String field) { final StringBuilder buffer = new StringBuilder(); final boolean hasBoost = (this.getBoost() != 1.0); buffer.append("("); for (int i = 0; i < clauses.size(); i++) { final NodeBooleanClause c = clauses.get(i); if (c.isProhibited()) buffer.append("-"); else if (c.isRequired()) buffer.append("+"); final Query subQuery = c.getQuery(); if (subQuery != null) { buffer.append(subQuery.toString(field)); } if (i != clauses.size() - 1) buffer.append(" "); } buffer.append(")"); if (hasBoost) { buffer.append(ToStringUtils.boost(this.getBoost())); } return buffer.toString(); }
@Override public Scorer scorer(final AtomicReaderContext context, final Bits acceptDocs) throws IOException { final List<NodeScorer> required = new ArrayList<NodeScorer>(); final List<NodeScorer> prohibited = new ArrayList<NodeScorer>(); final List<NodeScorer> optional = new ArrayList<NodeScorer>(); final Iterator<NodeBooleanClause> cIter = clauses.iterator(); for (final Weight w : weights) { final NodeBooleanClause c = cIter.next(); final NodeScorer subScorer = (NodeScorer) w.scorer(context, acceptDocs); if (subScorer == null) { if (c.isRequired()) { return null; } } else if (c.isRequired()) { required.add(subScorer); } else if (c.isProhibited()) { prohibited.add(subScorer); } else { optional.add(subScorer); } } if (required.size() == 0 && optional.size() == 0) { // no required and optional clauses. return null; } return new NodeBooleanScorer(this, required, prohibited, optional); }
@Override public void extractTerms(final Set<Term> terms) { for (final NodeBooleanClause clause : clauses) { clause.getQuery().extractTerms(terms); } }
if (clauses.size() == 1) { // optimize 1-clause queries final NodeBooleanClause c = clauses.get(0); if (!c.isProhibited()) { // just return clause NodeQuery query = (NodeQuery) c.getQuery().rewrite(reader); if (query == c.getQuery()) { // if rewrite was no-op final NodeQuery query = (NodeQuery) c.getQuery().rewrite(reader); if (query != c.getQuery()) { // clause rewrote: must clone if (clone == null) { clone = (NodeBooleanQuery) this.clone(); clone.clauses.set(i, new NodeBooleanClause(query, c.getOccur()));
/** * Adds a clause to a boolean query. * * @throws TooManyClauses * if the new number of clauses exceeds the maximum clause number * @see #getMaxClauseCount() */ public void add(final NodeQuery query, final NodeBooleanClause.Occur occur) { this.add(new NodeBooleanClause(query, occur)); }
@Test public void testTwigWithChildWithMissingOccur() throws QueryNodeException { final ExtendedTreeQueryParser parser = new ExtendedTreeQueryParser(); final String query = "{ \"twig\" : { \"child\" : " + "[ { \"node\" : { \"query\" : \"aaa\" } } ] " + "} }"; Query q = parser.parse(query, ""); // should not throw exception assertTrue(q instanceof LuceneProxyNodeQuery); q = ((LuceneProxyNodeQuery) q).getNodeQuery(); assertTrue(q instanceof com.sindicetech.siren.search.node.TwigQuery); Occur occur = ((com.sindicetech.siren.search.node.TwigQuery) q).getClauses()[0].getOccur(); assertEquals(parser.getDefaultOperator() == StandardQueryConfigHandler.Operator.AND ? Occur.MUST : Occur.SHOULD, occur); }
@Override public float getValueForNormalization() throws IOException { float sum = 0.0f; for (int i = 0; i < weights.size(); i++) { // call sumOfSquaredWeights for all clauses in case of side effects final float s = weights.get(i).getValueForNormalization(); // sum sub weights if (!clauses.get(i).isProhibited()) { // only add to sum for non-prohibited clauses sum += s; } } // boost each sub-weight sum *= NodeBooleanQuery.this.getBoost() * NodeBooleanQuery.this.getBoost(); return sum; }
@Override protected void initWeights(final IndexSearcher searcher) throws IOException { weights = new ArrayList<Weight>(clauses.size()); for (int i = 0; i < clauses.size(); i++) { final NodeBooleanClause c = clauses.get(i); final NodeQuery q = c.getQuery(); weights.add(q.createWeight(searcher)); } }
/** * Adds a descendant clause to the twig query. The node level of the * descendant is relative to the twig level. * * @throws TooManyClauses * if the new number of clauses exceeds the maximum clause number * @see #getMaxClauseCount() */ public void addDescendant(final int nodeLevel, final NodeQuery query, final NodeBooleanClause.Occur occur) { if (nodeLevel <= 0) { throw new IllegalArgumentException("The node level of a descendant should be superior to 0"); } // set the level constraint on the query query.setLevelConstraint(levelConstraint + nodeLevel); // set the ancestor pointer query.setAncestorPointer(root); // add the query to the clauses this.addClause(new NodeBooleanClause(query, occur)); }
final NodeScorer subScorer = (NodeScorer) w.scorer(context, acceptDocs); if (subScorer == null) { if (c.isRequired()) { return null; } else if (c.isRequired()) { required.add(subScorer); } else if (c.isProhibited()) { prohibited.add(subScorer); } else {
@Override public float getValueForNormalization() throws IOException { float sum = 0.0f; for (int i = 0; i < weights.size(); i++) { // call sumOfSquaredWeights for all clauses in case of side effects final float s = weights.get(i).getValueForNormalization(); // sum sub weights if (!clauses.get(i).isProhibited()) { // only add to sum for non-prohibited clauses sum += s; } } // incorporate root weight sum += rootWeight.getValueForNormalization(); // boost each weight sum *= TwigQuery.this.getBoost() * TwigQuery.this.getBoost(); return sum; }
/** * Adds a clause to a boolean query. * * @throws TooManyClauses * if the new number of clauses exceeds the maximum clause number * @see #getMaxClauseCount() */ public void add(final NodeBooleanClause clause) { if (clauses.size() >= maxClauseCount) { throw new TooManyClauses(); } clauses.add(clause); // keep the clause synchronised in term of constraint management clause.getQuery().setLevelConstraint(levelConstraint); clause.getQuery().setNodeConstraint(lowerBound, upperBound); clause.getQuery().setAncestorPointer(ancestor); }
if (c.isProhibited()) buffer.append("-"); else if (c.isRequired()) buffer.append("+"); final Query subQuery = c.getQuery(); if (subQuery != null) { if (subQuery instanceof TwigQuery ||
/** * Adds a child clause to the twig query. * * @throws TooManyClauses * if the new number of clauses exceeds the maximum clause number * @see #getMaxClauseCount() */ public void addChild(final NodeQuery query, final NodeBooleanClause.Occur occur) { // set the level constraint on the query query.setLevelConstraint(levelConstraint + 1); // set the ancestor pointer query.setAncestorPointer(root); // add the query to the clauses this.addClause(new NodeBooleanClause(query, occur)); }
final SpanScorer subScorer = (SpanScorer) wIter.next().scorer(context, acceptDocs); if (subScorer == null) { if (c.isRequired()) { return null; else if (c.isRequired()) { required.add(subScorer.getSpans()); else if (c.isProhibited()) { prohibited.add(subScorer.getSpans());
@Override public void setAncestorPointer(final NodeQuery ancestor) { super.setAncestorPointer(ancestor); // keep clauses synchronised for (final NodeBooleanClause clause : clauses) { clause.getQuery().setAncestorPointer(ancestor); } }