/** * Advance the internal document iterator to the specified document, or beyond if it doesn't. * * @param docid An internal document id. */ public void docIteratorAdvanceTo(int docid) { for (Qry q_i : this.args) { q_i.docIteratorAdvanceTo(docid); } this.docIteratorClearMatchCache(); }
/** * An instantiation of docIteratorHasMatch that is true if the query has a document that matches * the first query argument; some subclasses may choose to use this implementation. * * @param r The retrieval model that determines what is a match * @return True if the query matches, otherwise false. */ protected boolean docIteratorHasMatchFirst(RetrievalModel r) { Qry q_0 = this.args.get(0); if (q_0.docIteratorHasMatch(r)) { int docid = q_0.docIteratorGetMatch(); this.docIteratorSetMatchCache(docid); return true; } else { return false; } }
/** * An instantiation of docIteratorHasMatch that is true if the query has a document that matches * all query arguments; some subclasses may choose to use this implementation. * * @param r The retrieval model that determines what is a match * @return True if the query matches, otherwise false. */ protected boolean docIteratorHasMatchAll(RetrievalModel r) { boolean matchFound = false; // Keep trying until a match is found or no match is possible. while (!matchFound) { // Get the docid of the first query argument. Qry q_0 = this.args.get(0); if (!q_0.docIteratorHasMatch(r)) { return false; } int docid_0 = q_0.docIteratorGetMatch(); // Other query arguments must match the docid of the first query // argument. matchFound = true; for (int i = 1; i < this.args.size(); i++) { Qry q_i = this.args.get(i); q_i.docIteratorAdvanceTo(docid_0); if (!q_i.docIteratorHasMatch(r)) { // If any argument is exhausted return false; // there are no more matches. } int docid_i = q_i.docIteratorGetMatch(); if (docid_0 != docid_i) { // docid_0 can't match. Try again. q_0.docIteratorAdvanceTo(docid_i); matchFound = false; break; } } if (matchFound) { docIteratorSetMatchCache(docid_0); } } return true; }
/** * An instantiation of docIteratorHasMatch that is true if the query has a document that matches * at least one query argument; the match is the smallest docid to match; some subclasses may * choose to use this implementation. * * @param r The retrieval model that determines what is a match * @return True if the query matches, otherwise false. */ protected boolean docIteratorHasMatchMin(RetrievalModel r) { int minDocid = Qry.INVALID_DOCID; for (int i = 0; i < this.args.size(); i++) { Qry q_i = this.args.get(i); if (q_i.docIteratorHasMatch(r)) { int q_iDocid = q_i.docIteratorGetMatch(); if ((minDocid > q_iDocid) || (minDocid == Qry.INVALID_DOCID)) { minDocid = q_iDocid; } } } if (minDocid != Qry.INVALID_DOCID) { docIteratorSetMatchCache(minDocid); return true; } else { return false; } }
/** * Initialize the query operator (and its arguments), including any internal iterators. If the * query operator is of type QryIop, it is fully evaluated, and the results are stored in an * internal inverted list that may be accessed via the internal iterator. * * @param r A retrieval model that guides initialization * @throws IOException Error accessing the Lucene index. */ public void initialize(RetrievalModel r) throws IOException { for (Qry q_i : this.args) { q_i.initialize(r); } }
/** * Append an argument to the list of query operator arguments. * * @param q The query argument (query operator) to append. * @throws IllegalArgumentException q is an invalid argument */ public void appendArg(Qry q) throws IllegalArgumentException { // The query parser and query operator type system are too simple // to detect some kinds of query syntax errors. appendArg does // additional syntax checking while creating the query tree. It // also inserts SCORE operators between QrySop operators and QryIop // arguments, and propagates field information from QryIop // children to parents. Basically, it creates a well-formed // query tree. if (this instanceof QryIopTerm) { throw new IllegalArgumentException("The TERM operator has no arguments."); } // SCORE operators can have only a single argument of type QryIop. if (this instanceof QrySopScore) { if (this.args.size() > 0) { throw new IllegalArgumentException("Score operators can have only one argument"); } else if (!(q instanceof QryIop)) { throw new IllegalArgumentException( "The argument to a SCORE operator must be of type QryIop."); } else { this.args.add(q); return; } } // Check whether it is necessary to insert an implied SCORE // operator between a QrySop operator and a QryIop argument. if ((this instanceof QrySop) && (q instanceof QryIop)) { Qry impliedOp = new QrySopScore(); impliedOp.setDisplayName("#SCORE"); impliedOp.appendArg(q); this.args.add(impliedOp); return; } // QryIop operators must have QryIop arguments in the same field. if ((this instanceof QryIop) && (q instanceof QryIop)) { if (this.args.size() == 0) { ((QryIop) this).field = new String(((QryIop) q).getField()); } else { if (!((QryIop) this).field.equals(((QryIop) q).getField())) { throw new IllegalArgumentException( "Arguments to QryIop operators must be in the same field."); } } this.args.add(q); return; } // QrySop operators and their arguments must be of the same type. if ((this instanceof QrySop) && (q instanceof QrySop)) { this.args.add(q); return; } throw new IllegalArgumentException( "Objects of type " + q.getClass().getName() + " cannot be an argument to a query operator of type " + this.getClass().getName()); }
/** * Initialize the query operator (and its arguments), including any internal iterators. If the * query operator is of type QryIop, it is fully evaluated, and the results are stored in an * internal inverted list that may be accessed via the internal iterator. * * @param r A retrieval model that guides initialization * @throws IOException Error accessing the Lucene index. */ public void initialize(RetrievalModel r) throws IOException { Qry q = this.args.get(0); q.initialize(r); }