Mercurial Hosting > luan
view lucene/src/luan/modules/lucene/LuceneSearcher.java @ 232:9ce18106f95a
more lucene work
git-svn-id: https://luan-java.googlecode.com/svn/trunk@233 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Wed, 01 Oct 2014 06:55:14 +0000 |
parents | 4438cb2e04d0 |
children | ef39bc4d3f70 |
line wrap: on
line source
package luan.modules.lucene; import java.io.IOException; import java.util.NoSuchElementException; import java.util.Map; import java.util.List; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.Term; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopFieldDocs; import org.apache.lucene.search.Sort; import org.apache.lucene.search.SortField; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TermQuery; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.BooleanClause; import luan.Luan; import luan.LuanState; import luan.LuanTable; import luan.LuanFunction; import luan.LuanJavaFunction; import luan.LuanException; public final class LuceneSearcher { private final IndexSearcher searcher; LuceneSearcher(IndexReader reader) { this.searcher = new IndexSearcher(reader); } // call in finally block void close() { try { searcher.getIndexReader().decRef(); } catch(IOException e) { throw new RuntimeException(e); } } public LuanTable doc(int docID) throws IOException { return LuceneDocument.toTable(searcher.doc(docID)); } TopDocs search(Query query,int n) throws IOException { return searcher.search(query,n); } TopFieldDocs search(Query query,int n,Sort sort) throws IOException { return searcher.search(query,n,sort); } // luan private Query termQuery(Map<Object,Object> map) { if( map.size() != 1 ) return null; Map.Entry<Object,Object> entry = map.entrySet().iterator().next(); Object key = entry.getKey(); Object value = entry.getValue(); if( key instanceof String && value instanceof String ) { return new TermQuery(new Term( (String)key, (String)value )); } return null; } private Query booleanQuery(Map<Object,Object> map) { BooleanQuery query = new BooleanQuery(); for( Map.Entry<Object,Object> entry : map.entrySet() ) { Object key = entry.getKey(); Object value = entry.getValue(); if( !(key instanceof String && value instanceof LuanTable) ) return null; Query subQuery = query( (LuanTable)value ); if( subQuery == null ) return null; BooleanClause.Occur occur; try { occur = BooleanClause.Occur.valueOf( ((String)key).toUpperCase() ); } catch(IllegalArgumentException e) { return null; } query.add(subQuery,occur); } return query; } private Query query(LuanTable queryTbl) { Map<Object,Object> map = queryTbl.asMap(); if( map.isEmpty() ) return null; Query query; query = termQuery(map); if(query!=null) return query; query = booleanQuery(map); if(query!=null) return query; return null; } private SortField sortField(LuanState luan,List<Object> list,String pos) throws LuanException { int size = list.size(); if( size < 2 || size > 3 ) throw luan.exception("invalid sort field"+pos); Object obj0 = list.get(0); Object obj1 = list.get(1); if( !(obj0 instanceof String && obj1 instanceof String) ) throw luan.exception("invalid sort field"+pos); String field = (String)obj0; SortField.Type type; try { type = SortField.Type.valueOf( ((String)obj1).toUpperCase() ); } catch(IllegalArgumentException e) { throw luan.exception("invalid sort field type"+pos); } if( size == 2 ) return new SortField(field,type); Object obj2 = list.get(2); if( !(obj2 instanceof Boolean) ) throw luan.exception("invalid sort field"+pos+", 'reverse' must be boolean"); boolean reverse = (Boolean)obj2; return new SortField(field,type,reverse); } private Sort sort(LuanState luan,LuanTable sortTbl) throws LuanException { if( !sortTbl.isList() ) throw luan.exception("invalid sort, must be list"); List<Object> list = sortTbl.asList(); if( list.isEmpty() ) throw luan.exception("sort cannot be empty"); if( list.get(0) instanceof String ) return new Sort(sortField(luan,list,"")); SortField[] flds = new SortField[list.size()]; for( int i=0; i<flds.length; i++ ) { Object obj = list.get(i); if( !(obj instanceof LuanTable) ) throw luan.exception("invalid sort parameter at position "+(i+1)); LuanTable fldTbl = (LuanTable)obj; if( !fldTbl.isList() ) throw luan.exception("invalid sort field at position "+(i+1)+", must be list"); flds[i] = sortField(luan,fldTbl.asList()," at position "+(i+1)); } return new Sort(flds); } public Object[] search( LuanState luan, LuanTable queryTbl, int n, LuanTable sortTbl ) throws LuanException, IOException { Query query = query(queryTbl); if( query == null ) throw luan.exception("invalid query"); TopDocs td = sortTbl==null ? searcher.search(query,n) : searcher.search(query,n,sort(luan,sortTbl)); final ScoreDoc[] scoreDocs = td.scoreDocs; LuanFunction results = new LuanFunction() { int i = 0; @Override public Object call(LuanState luan,Object[] args) throws LuanException { if( i >= scoreDocs.length ) return LuanFunction.NOTHING; try { LuanTable doc = doc(scoreDocs[i++].doc); return doc; } catch(IOException e) { throw luan.exception(e); } } }; return new Object[]{ results, scoreDocs.length, td.totalHits }; } private void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException { t.put( method, new LuanJavaFunction(LuceneSearcher.class.getMethod(method,parameterTypes),this) ); } LuanTable table() { LuanTable tbl = Luan.newTable(); try { add( tbl, "search", LuanState.class, LuanTable.class, Integer.TYPE, LuanTable.class ); } catch(NoSuchMethodException e) { throw new RuntimeException(e); } return tbl; } }