Sie können sich überlegen, alle Dokumente durchzugehen, die Kategorien mit einer TermDocs iterator entsprechen.
Dieser Beispielcode durchläuft jeden "Kategorie" -Begriff und zählt dann die Anzahl der Dokumente, die mit diesem Begriff übereinstimmen.
public static void countDocumentsInCategories(IndexReader reader) throws IOException {
TermEnum terms = null;
TermDocs td = null;
try {
terms = reader.terms(new Term("Category", ""));
td = reader.termDocs();
do {
Term currentTerm = terms.term();
if (!currentTerm.field().equals("Category")) {
break;
}
int numDocs = 0;
td.seek(terms);
while (td.next()) {
numDocs++;
}
System.out.println(currentTerm.field() + " : " + currentTerm.text() + " --> " + numDocs);
} while (terms.next());
} finally {
if (td != null) td.close();
if (terms != null) terms.close();
}
}
Dieser Code sollte auch für große Indizes einigermaßen schnell ausgeführt werden.
Hier ist ein Code, der diese Methode testet: (!)
public static void main(String[] args) throws Exception {
RAMDirectory store = new RAMDirectory();
IndexWriter w = new IndexWriter(store, new StandardAnalyzer());
addDocument(w, 1, "Apple", "fruit", "computer");
addDocument(w, 2, "Orange", "fruit", "colour");
addDocument(w, 3, "Dell", "computer");
addDocument(w, 4, "Cumquat", "fruit");
w.close();
IndexReader r = IndexReader.open(store);
countDocumentsInCategories(r);
r.close();
}
private static void addDocument(IndexWriter w, int id, String name, String... categories) throws IOException {
Document d = new Document();
d.add(new Field("ID", String.valueOf(id), Field.Store.YES, Field.Index.UN_TOKENIZED));
d.add(new Field("Name", name, Field.Store.NO, Field.Index.UN_TOKENIZED));
for (String category : categories) {
d.add(new Field("Category", category, Field.Store.NO, Field.Index.UN_TOKENIZED));
}
w.addDocument(d);
}
Dies zählt nur die Dokumente, die von jedem Begriff im Feld Category markiert sind, was Sie mit terms.docFreq() viel schneller machen könnten. Was fehlt, ist die Schnittmenge mit den Treffern aus den Suchkriterien des Nutzers. – erickson