package org.elasticsearch.index.query.image; import net.semanticmetadata.lire.imageanalysis.LireFeature; import org.apache.lucene.index.AtomicReaderContext; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.search.*; import org.apache.lucene.util.Bits; import org.apache.lucene.util.ToStringUtils; import java.io.IOException; import java.util.Set; /** * Copied from {@link MatchAllDocsQuery}, calculate score for all docs */ public class ImageQuery extends Query { private String luceneFieldName; private LireFeature lireFeature; public ImageQuery(String luceneFieldName, LireFeature lireFeature, float boost) { this.luceneFieldName = luceneFieldName; this.lireFeature = lireFeature; setBoost(boost); } private class ImageScorer extends AbstractImageScorer { private int doc = -1; private final int maxDoc; private final Bits liveDocs; ImageScorer(IndexReader reader, Bits liveDocs, Weight w) { super(w, luceneFieldName, lireFeature, reader, ImageQuery.this.getBoost()); this.liveDocs = liveDocs; maxDoc = reader.maxDoc(); } @Override public int docID() { return doc; } @Override public int nextDoc() throws IOException { doc++; while(liveDocs != null && doc < maxDoc && !liveDocs.get(doc)) { doc++; } if (doc == maxDoc) { doc = NO_MORE_DOCS; } return doc; } @Override public int advance(int target) throws IOException { doc = target-1; return nextDoc(); } @Override public long cost() { return maxDoc; } } private class ImageWeight extends Weight { public ImageWeight(IndexSearcher searcher) { } @Override public String toString() { return "weight(" + ImageQuery.this + ")"; } @Override public Query getQuery() { return ImageQuery.this; } @Override public float getValueForNormalization() { return 1f; } @Override public void normalize(float queryNorm, float topLevelBoost) { } @Override public Scorer scorer(AtomicReaderContext context, Bits acceptDocs) throws IOException { return new ImageScorer(context.reader(), acceptDocs, this); } @Override public Explanation explain(AtomicReaderContext context, int doc) throws IOException { Scorer scorer = scorer(context, context.reader().getLiveDocs()); if (scorer != null) { int newDoc = scorer.advance(doc); if (newDoc == doc) { float score = scorer.score(); ComplexExplanation result = new ComplexExplanation(); result.setDescription("ImageQuery, product of:"); result.setValue(score); if (getBoost() != 1.0f) { result.addDetail(new Explanation(getBoost(),"boost")); score = score / getBoost(); } result.addDetail(new Explanation(score ,"image score (1/distance)")); result.setMatch(true); return result; } } return new ComplexExplanation(false, 0.0f, "no matching term"); } } @Override public Weight createWeight(IndexSearcher searcher) { return new ImageWeight(searcher); } @Override public void extractTerms(Set<Term> terms) { } @Override public String toString(String field) { StringBuilder buffer = new StringBuilder(); buffer.append(luceneFieldName); buffer.append(","); buffer.append(lireFeature.getClass().getSimpleName()); buffer.append(ToStringUtils.boost(getBoost())); return buffer.toString(); } @Override public boolean equals(Object o) { if (!(o instanceof ImageQuery)) return false; ImageQuery other = (ImageQuery) o; return (this.getBoost() == other.getBoost()) && luceneFieldName.equals(luceneFieldName) && lireFeature.equals(lireFeature); } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + luceneFieldName.hashCode(); result = 31 * result + lireFeature.hashCode(); result = Float.floatToIntBits(getBoost()) ^ result; return result; } }