package com.senseidb.clue.commands; import java.io.IOException; import java.io.PrintStream; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.LeafReader; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.index.FieldInfo; import org.apache.lucene.index.FieldInfos; import org.apache.lucene.index.Fields; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.SegmentCommitInfo; import org.apache.lucene.index.SegmentInfos; import org.apache.lucene.index.Terms; import com.senseidb.clue.ClueContext; public class InfoCommand extends ClueCommand { public InfoCommand(ClueContext ctx) { super(ctx); } @Override public String getName() { return "info"; } @Override public String help() { return "displays information about the index, <segment number> to get information on the segment"; } @SuppressWarnings("unchecked") private static void toString(Object[] info, PrintStream out) throws IOException { FieldInfo finfo = (FieldInfo) info[0]; List<Terms> termList = (List<Terms>) info[1]; out.println("name:\t\t" + finfo.name); out.println("docval_type:\t" + finfo.getDocValuesType()); out.println("norms:\t\t" + finfo.hasNorms()); IndexOptions indexOptions = finfo.getIndexOptions(); if (indexOptions != null) { out.println("index_options:\t" + finfo.getIndexOptions().name()); } out.println("payloads:\t" + finfo.hasPayloads()); out.println("vectors:\t" + finfo.hasVectors()); out.println("attributes:\t" + finfo.attributes().toString()); if (termList != null) { long numTerms = 0L; long docCount = 0L; long sumDocFreq = 0L; long sumTotalTermFreq = 0L; for (Terms t : termList) { if (t != null) { numTerms += t.size(); docCount += t.getDocCount(); sumDocFreq += t.getSumDocFreq(); sumTotalTermFreq += t.getSumTotalTermFreq(); } } if (numTerms < 0) { numTerms = -1; } if (docCount < 0) { docCount = -1; } if (sumDocFreq < 0) { sumDocFreq = -1; } if (sumTotalTermFreq < 0) { sumTotalTermFreq = -1; } out.println("num_terms:\t" + numTerms); out.println("doc_count:\t" + docCount); out.println("sum_doc_freq:\t" + sumDocFreq); out.println("sum_total_term_freq:\t" + sumTotalTermFreq); } } @Override @SuppressWarnings("unchecked") public void execute(String[] args, PrintStream out) throws Exception { IndexReader r = ctx.getIndexReader(); out.println("readonly mode: " + getContext().isReadOnlyMode()); if (r instanceof DirectoryReader) { DirectoryReader dr = (DirectoryReader)r; SegmentInfos sis = SegmentInfos.readLatestCommit(dr.directory()); // read infos from dir for (SegmentCommitInfo commitInfo : sis) { if (commitInfo != null) { out.println("Codec found: " + commitInfo.info.getCodec().getName()); break; } } } List<LeafReaderContext> leaves = r.leaves(); if (args.length == 0) { out.println("numdocs: " + r.numDocs()); out.println("maxdoc: " + r.maxDoc()); out.println("num deleted docs: " + r.numDeletedDocs()); out.println("segment count: " + leaves.size()); SortedMap<String, Object[]> fields = new TreeMap<String, Object[]>(); for (LeafReaderContext leaf : leaves) { LeafReader ar = leaf.reader(); FieldInfos fldInfos = ar.getFieldInfos(); Iterator<FieldInfo> finfoIter = fldInfos.iterator(); Fields flds = ar.fields(); while (finfoIter.hasNext()) { FieldInfo finfo = finfoIter.next(); Object[] data = fields.get(finfo.name); Terms t = flds.terms(finfo.name); if (data == null) { data = new Object[2]; LinkedList<Terms> termsList = new LinkedList<Terms>(); termsList.add(t); data[0] = finfo; data[1] = termsList; fields.put(finfo.name, data); } else { List<Terms> termsList = (List<Terms>) data[1]; termsList.add(t); } } } out.println("number of fields: " + fields.size()); for (Object[] finfo : fields.values()) { FieldInfo f = (FieldInfo) finfo[0]; out.println("=================================== Field "+f.name+" ==================================="); toString(finfo, out); } } else { int segid; try { segid = Integer.parseInt(args[0]); if (segid < 0 || segid >= leaves.size()) { throw new IllegalArgumentException("invalid segment"); } } catch (Exception e) { out.println("segment id must be a number betweem 0 and " + (leaves.size() - 1)); return; } LeafReaderContext leaf = leaves.get(segid); LeafReader atomicReader = leaf.reader(); out.println("segment " + segid + ": "); out.println("doc base:\t" + leaf.docBase); out.println("numdocs:\t" + atomicReader.numDocs()); out.println("maxdoc:\t" + atomicReader.maxDoc()); out.println("num deleted docs:\t" + atomicReader.numDeletedDocs()); FieldInfos fields = atomicReader.getFieldInfos(); Fields flds = atomicReader.fields(); out.println("number of fields: " + fields.size()); for (int i = 0; i < fields.size(); ++i) { FieldInfo finfo = fields.fieldInfo(i); Terms te = flds.terms(finfo.name); out.println("=================================== Field "+finfo.name+" ==================================="); toString(new Object[] { finfo, Arrays.asList(te) }, out); } } out.flush(); } }