mirror of https://github.com/apache/lucene.git
Add Hits.iterator and corresponding HitIterator and Hit classes. Contributed by Jeremy Rayner
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@164695 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d650384d4b
commit
ab83a46657
|
@ -91,6 +91,11 @@ New features
|
|||
which lets the caller get the Lucene version information specified in
|
||||
the Lucene Jar.
|
||||
(Doug Cutting via Otis)
|
||||
|
||||
15. Added Hits.iterator() method and corresponding HitIterator and Hit objects.
|
||||
This provides standard java.util.Iterator iteration over Hits.
|
||||
Each call to the iterator's next() method returns a Hit object.
|
||||
(Jeremy Rayner via Erik)
|
||||
|
||||
API Changes
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* Copyright 2005 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.lucene.search;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
|
||||
/**
|
||||
* a lazy future for a hit, useful for iterators over instances of Hits
|
||||
*
|
||||
* @author Jeremy Rayner
|
||||
*/
|
||||
public class Hit implements java.io.Serializable {
|
||||
|
||||
private float score;
|
||||
private int id;
|
||||
private Document doc = null;
|
||||
|
||||
private boolean resolved = false;
|
||||
|
||||
private Hits hits = null;
|
||||
private int hitNumber;
|
||||
|
||||
/**
|
||||
* Constructed from {@link HitIterator}
|
||||
* @param hits Hits returned from a search
|
||||
* @param hitNumber Hit index in Hits
|
||||
*/
|
||||
Hit(Hits hits, int hitNumber) {
|
||||
this.hits = hits;
|
||||
this.hitNumber = hitNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns document for this hit.
|
||||
*
|
||||
* @see {@link Hits#doc(int)}
|
||||
*/
|
||||
public Document getDocument() throws IOException {
|
||||
if (!resolved) fetchTheHit();
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns score for this hit.
|
||||
*
|
||||
* @see {@link Hits#score(int)}
|
||||
*/
|
||||
public float getScore() throws IOException {
|
||||
if (!resolved) fetchTheHit();
|
||||
return score;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns id for this hit.
|
||||
*
|
||||
* @see {@link Hits#id(int)}
|
||||
*/
|
||||
public int getId() throws IOException {
|
||||
if (!resolved) fetchTheHit();
|
||||
return id;
|
||||
}
|
||||
|
||||
private void fetchTheHit() throws IOException {
|
||||
doc = hits.doc(hitNumber);
|
||||
score = hits.score(hitNumber);
|
||||
id = hits.id(hitNumber);
|
||||
resolved = true;
|
||||
}
|
||||
|
||||
// provide some of the Document style interface (the simple stuff)
|
||||
|
||||
/**
|
||||
* Returns the boost factor for this hit on any field of the underlying document.
|
||||
*
|
||||
* @see {@link Document#getBoost()}
|
||||
*/
|
||||
public float getBoost() throws IOException {
|
||||
return getDocument().getBoost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string value of the field with the given name if any exist in
|
||||
* this document, or null. If multiple fields exist with this name, this
|
||||
* method returns the first value added. If only binary fields with this name
|
||||
* exist, returns null.
|
||||
*
|
||||
* @see {@link Document#get(String)}
|
||||
*/
|
||||
public String get(String name) throws IOException {
|
||||
return getDocument().get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the fields of the underlying document for human consumption.
|
||||
* <p/>
|
||||
* If an IOException occurs whilst getting the document, returns null
|
||||
*
|
||||
* @see {@link Document#toString()}
|
||||
*/
|
||||
public String toString() {
|
||||
try {
|
||||
return getDocument().toString();
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Copyright 2005 The Apache Software Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.lucene.search;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
* An iterator over {@link Hits} that provides lazy fetching of each document.
|
||||
* {@link Hits#iterator()} returns an instance of this class. Calls to {@link #next()}
|
||||
* return a {@link Hit} instance.
|
||||
*
|
||||
* @author Jeremy Rayner
|
||||
*/
|
||||
public class HitIterator implements Iterator {
|
||||
private Hits hits;
|
||||
private int hitNumber = 0;
|
||||
|
||||
/**
|
||||
* Constructed from {@link Hits#iterator()}.
|
||||
*/
|
||||
HitIterator(Hits hits) {
|
||||
this.hits = hits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if current hit is less than the total number of {@link Hits}.
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return hitNumber < hits.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Hit} instance representing the next hit in {@link Hits}.
|
||||
*
|
||||
* @return Next {@link Hit}.
|
||||
*/
|
||||
public Object next() {
|
||||
try {
|
||||
Object next = new Hit(hits, hitNumber);
|
||||
hitNumber++;
|
||||
return next;
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsupported operation.
|
||||
*
|
||||
* @throws UnsupportedOperationException
|
||||
*/
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of hits.
|
||||
*/
|
||||
public int length() {
|
||||
return hits.length();
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ package org.apache.lucene.search;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Vector;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
|
||||
|
@ -114,6 +115,13 @@ public final class Hits {
|
|||
return hitDoc(n).id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an {@link Iterator} to navigate the Hits. Each item returned
|
||||
* from {@link Iterator#next()} is a {@link Hit}.
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
return new HitIterator(this);
|
||||
}
|
||||
|
||||
private final HitDoc hitDoc(int n) throws IOException {
|
||||
if (n >= length) {
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package org.apache.lucene;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
import org.apache.lucene.search.IndexSearcher;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.Hits;
|
||||
import org.apache.lucene.search.Hit;
|
||||
import org.apache.lucene.search.HitIterator;
|
||||
|
||||
/**
|
||||
* This test intentionally not put in the search package in order
|
||||
* to test HitIterator and Hit package protection.
|
||||
*/
|
||||
public class TestHitIterator extends TestCase {
|
||||
public void testIterator() throws Exception {
|
||||
RAMDirectory directory = new RAMDirectory();
|
||||
|
||||
IndexWriter writer = new IndexWriter(directory, new WhitespaceAnalyzer(), true);
|
||||
Document doc = new Document();
|
||||
doc.add(new Field("field", "iterator test doc 1", Field.Store.YES, Field.Index.TOKENIZED));
|
||||
writer.addDocument(doc);
|
||||
|
||||
doc = new Document();
|
||||
doc.add(new Field("field", "iterator test doc 2", Field.Store.YES, Field.Index.TOKENIZED));
|
||||
writer.addDocument(doc);
|
||||
|
||||
writer.close();
|
||||
|
||||
IndexSearcher searcher = new IndexSearcher(directory);
|
||||
Hits hits = searcher.search(new TermQuery(new Term("field", "iterator")));
|
||||
|
||||
HitIterator iterator = (HitIterator) hits.iterator();
|
||||
assertEquals(2, iterator.length());
|
||||
assertTrue(iterator.hasNext());
|
||||
Hit hit = (Hit) iterator.next();
|
||||
assertEquals("iterator test doc 1", hit.get("field"));
|
||||
|
||||
assertTrue(iterator.hasNext());
|
||||
hit = (Hit) iterator.next();
|
||||
assertEquals("iterator test doc 2", hit.getDocument().get("field"));
|
||||
|
||||
assertFalse(iterator.hasNext());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue