@Override public boolean skipToCandidate(final int target) throws IOException { if (lastDocument == DocsAndNodesIterator.NO_MORE_DOC) { return false; } else if (scorers[(scorers.length - 1)].doc() < target) { scorers[(scorers.length - 1)].skipToCandidate(target); } final boolean more = this.doNext(); lastDocument = scorers[scorers.length - 1].doc(); lastNode = scorers[scorers.length - 1].node(); return more; }
/** * Compute the score and the frequency of the current document * @throws IOException */ private void computeScoreAndFreq() throws IOException { final int doc = this.docID(); if (doc != lastDoc) { lastDoc = doc; score = 0; freq = 0; do { // nextNode() was already called in nextDoc() or in advance() score += scorer.scoreInNode(); freq += scorer.freqInNode(); } while (scorer.nextNode()); } }
@Override public int advance(final int target) throws IOException { if (scorer.skipToCandidate(target)) { do { if (scorer.nextNode()) { return this.docID(); } } while (scorer.nextCandidateDocument()); } return NO_MORE_DOCS; }
/** * Perform a next without initial increment */ private boolean doNext() throws IOException { int first = 0; int doc = scorers[scorers.length - 1].doc(); NodeScorer firstScorer = scorers[first]; boolean more = true; while (firstScorer.doc() < doc) { more = firstScorer.skipToCandidate(doc); doc = firstScorer.doc(); first = first == scorers.length - 1 ? 0 : first + 1; firstScorer = scorers[first]; } return more; }
@Override public float scoreInNode() throws IOException { final float reqScore = reqScorer.scoreInNode(); final int doc = this.doc(); if (optScorer == null) { return reqScore; } else if (optScorer.doc() < doc && // if it is the first call, optScorer.doc() returns -1 !optScorer.skipToCandidate(doc)) { optScorer = null; return reqScore; } final IntsRef reqNode = this.node(); /* * the optional scorer can be in a node that is before the one where * the required scorer is in. */ int cmp = 1; while ((cmp = NodeUtils.compare(optScorer.node(), reqNode)) < 0) { if (!optScorer.nextNode()) { return reqScore; } } // If the optional scorer matches the same node, increase the score return (optScorer.doc() == doc && cmp == 0) ? reqScore + optScorer.scoreInNode() : reqScore; }
@Test public void testNoNode() throws IOException { this.addDocument("\"eee\" . \"ddd\" . "); final NodeScorer scorer = this.getScorer( nbq(must("ddd"), must("eee")) ); assertTrue(scorer.nextCandidateDocument()); assertFalse(scorer.nextNode()); assertEquals(DocsAndNodesIterator.NO_MORE_NOD, scorer.node()); assertEndOfStream(scorer); }
@Override public boolean nextCandidateDocument() throws IOException { if (lastDocument == DocsAndNodesIterator.NO_MORE_DOC) { return false; } else if (lastDocument == -1) { // first time called lastDocument = scorers[scorers.length - 1].doc(); lastNode = scorers[scorers.length - 1].node(); return true; } // advance the last scorer to the next candidate document scorers[(scorers.length - 1)].nextCandidateDocument(); final boolean more = this.doNext(); lastDocument = scorers[scorers.length - 1].doc(); lastNode = scorers[scorers.length - 1].node(); return more; }
int exclDoc = exclScorer.doc(); final int reqDoc = reqScorer.doc(); // may be excluded if (!exclScorer.skipToCandidate(reqDoc)) { exclDoc = exclScorer.doc(); if (exclDoc >= reqDoc) { return true; // exclScorer advanced to or before reqScorer, not excluded } while (reqScorer.nextCandidateDocument());
@Override public Explanation explain(final AtomicReaderContext context, final int doc) throws IOException { final NodeScorer cs = (NodeScorer) this.scorer(context, true, false, context.reader().getLiveDocs()); final boolean exists = (cs != null && cs.skipToCandidate(doc) && cs.doc() == doc && cs.nextNode()); final ComplexExplanation result = new ComplexExplanation(); if (exists) { result.setDescription(NodeConstantScoreQuery.this.toString() + ", product of:"); result.setValue(queryWeight); result.setMatch(Boolean.TRUE); result.addDetail(new Explanation(NodeConstantScoreQuery.this.getBoost(), "boost")); result.addDetail(new Explanation(queryNorm, "queryNorm")); } else { result.setDescription(NodeConstantScoreQuery.this.toString() + " doesn't match id " + doc); result.setValue(0); result.setMatch(Boolean.FALSE); } return result; } }
@Override public float scoreInNode() throws IOException { float curNodeScore = 0; for (final NodeScorer scorer : scorers) { curNodeScore += scorer.scoreInNode(); } // TODO: why is there a coord here ? return curNodeScore * coord; }
@Override public boolean nextCandidateDocument() throws IOException { return scorer.nextCandidateDocument(); }
@Override public int doc() { return reqScorer.doc(); }
@Override public boolean nextNode() throws IOException { if (!reqScorer.nextNode()) { // Move to the next matching node return false; // exhausted, nothing left } if (exclScorer == null || exclScorer.doc() != reqScorer.doc()) { return true; // reqScorer.nextNode() already returned true } // reqScorer and exclScorer are positioned on the same candidate document return this.toNonExcludedNode(); }
@Override public boolean skipToCandidate(final int target) throws IOException { return scorer.skipToCandidate(target); }
@Override public int nextDoc() throws IOException { while (scorer.nextCandidateDocument()) { if (scorer.nextNode()) { // check if there is at least 1 node that matches the query return this.docID(); } } return NO_MORE_DOCS; }
@Override public IntsRef node() { final IntsRef node = scorer.node(); // resize node array only if node is not a sentinel value if (node.length > ancestorLevel && node.ints[node.offset] != -1 && node != DocsAndNodesIterator.NO_MORE_NOD) { node.length = ancestorLevel; } return node; }
@Override public boolean nextNode() throws IOException { return scorer.nextNode(); }
@Override public float freqInNode() throws IOException { return scorer.freqInNode(); }
public AncestorFilterScorer(final NodeScorer scorer, final int ancestorLevel) { super(scorer.getWeight()); this.scorer = scorer; this.ancestorLevel = ancestorLevel; }