changeset 287:4d53e9fc1bd9

change lucene search to take lucene objects git-svn-id: https://luan-java.googlecode.com/svn/trunk@288 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Thu, 04 Dec 2014 09:27:20 +0000
parents 91be4027b2a8
children c4ed33e95889
files core/src/luan/impl/BinaryOpExpr.java dist/jars/luan-core-trunk.jar dist/jars/luan-logging-trunk.jar dist/jars/luan-lucene-trunk.jar dist/jars/luan-mail-trunk.jar dist/jars/luan-web-trunk.jar lucene/src/luan/modules/lucene/Lucene.luan lucene/src/luan/modules/lucene/LuceneIndex.java lucene/src/luan/modules/lucene/LuceneSearcher.java lucene/src/luan/modules/lucene/Web_search.luan
diffstat 10 files changed, 89 insertions(+), 128 deletions(-) [+]
line wrap: on
line diff
--- a/core/src/luan/impl/BinaryOpExpr.java	Wed Dec 03 02:26:19 2014 +0000
+++ b/core/src/luan/impl/BinaryOpExpr.java	Thu Dec 04 09:27:20 2014 +0000
@@ -18,7 +18,7 @@
 	}
 
 	Object arithmetic(LuanStateImpl luan,String op,Object o1,Object o2) throws LuanException {
-		return luan.bit(se()).arithmetic("__mod",o1,o2);
+		return luan.bit(se()).arithmetic(op,o1,o2);
 	}
 
 }
Binary file dist/jars/luan-core-trunk.jar has changed
Binary file dist/jars/luan-logging-trunk.jar has changed
Binary file dist/jars/luan-lucene-trunk.jar has changed
Binary file dist/jars/luan-mail-trunk.jar has changed
Binary file dist/jars/luan-web-trunk.jar has changed
--- a/lucene/src/luan/modules/lucene/Lucene.luan	Wed Dec 03 02:26:19 2014 +0000
+++ b/lucene/src/luan/modules/lucene/Lucene.luan	Thu Dec 04 09:27:20 2014 +0000
@@ -1,5 +1,13 @@
+import "luan:Table"
 import "luan:Java"
 import "java:luan.modules.lucene.LuceneIndex"
+import "java:org.apache.lucene.index.Term"
+import "java:org.apache.lucene.search.TermQuery"
+import "java:org.apache.lucene.search.MatchAllDocsQuery"
+import "java:org.apache.lucene.search.BooleanQuery"
+import "java:org.apache.lucene.search.BooleanClause"
+import "java:org.apache.lucene.search.Sort"
+import "java:org.apache.lucene.search.SortField"
 
 
 function Index(indexDir)
@@ -39,5 +47,69 @@
 		end )
 	end
 
+
+
+	local Query = {}
+	index.Query = Query
+
+	Query.all_docs = MatchAllDocsQuery.new()
+	
+	function Query.term(t)
+		local iter = pairs(t)
+		local field, value = iter()
+		field and value or error "missing term"
+		iter()==nil or error "only one term allowed"
+		field = index.map_field_name(field)
+		return TermQuery.new(Term.new(field,value))
+	end
+	
+	function Query.boolean(t)
+		local boolean_query = BooleanQuery.new()
+		for query, occur_string in pairs(t) do
+			local occur = BooleanClause.Occur.valueOf( occur_string.upper() )
+			boolean_query.add( query, occur )
+		end
+		return boolean_query
+	end
+	
+	-- and list
+	function Query.all(t)
+		local bt = {}
+		for key, query in pairs(t) do
+			if type(key)=="string" then
+				query = Query.term{[key]=query}
+			end
+			bt[query] = "MUST"
+		end
+		return Query.boolean(bt)
+	end
+	
+	-- or list
+	function Query.any(t)
+		local bt = {}
+		for key, query in pairs(t) do
+			if type(key)=="string" then
+				query = Query.term{[key]=query}
+			end
+			bt[query] = "SHOULD"
+		end
+		return Query.boolean(bt)
+	end
+	
+	
+	function Query.sort(fields)
+		#fields > 0 or error "list of sort fields expected"
+		local a = {}
+		for _, f in ipairs(fields) do
+			f.field or error "missing sort field"
+			f.type or error "missing sort type"
+			local type = SortField.Type.valueOf( f.type.upper() )
+			local reverse = f.reverse or false
+			a[#a+1] = SortField.new(f.field,type,reverse)
+		end
+		return Sort.new(Table.unpack(a))
+	end
+
+
 	return index
 end
--- a/lucene/src/luan/modules/lucene/LuceneIndex.java	Wed Dec 03 02:26:19 2014 +0000
+++ b/lucene/src/luan/modules/lucene/LuceneIndex.java	Thu Dec 04 09:27:20 2014 +0000
@@ -65,13 +65,13 @@
 		return LuceneDocument.toTable(luan,doc,fields.reverseMap);
 	}
 
-	String fixFieldName(String fld) {
+	public String map_field_name(String fld) {
 		String s = fields.map.get(fld);
 		return s!=null ? s : fld;
 	}
 
 	Term newTerm(String fld,String text) {
-		return new Term(fixFieldName(fld),text);
+		return new Term(map_field_name(fld),text);
 	}
 
 	public LuceneWriter openWriter() {
@@ -196,6 +196,7 @@
 			add( tbl, "Writer", LuanState.class, LuanFunction.class );
 			add( tbl, "Searcher", LuanState.class, LuanFunction.class );
 			add( tbl, "delete_all" );
+			add( tbl, "map_field_name", String.class );
 		} catch(NoSuchMethodException e) {
 			throw new RuntimeException(e);
 		}
--- a/lucene/src/luan/modules/lucene/LuceneSearcher.java	Wed Dec 03 02:26:19 2014 +0000
+++ b/lucene/src/luan/modules/lucene/LuceneSearcher.java	Thu Dec 04 09:27:20 2014 +0000
@@ -58,113 +58,6 @@
 
 	// luan
 
-	private Query termQuery(LuanTable queryTbl) {
-		if( queryTbl.length() != 0 )
-			return null;
-		Map<Object,Object> map = queryTbl.asMap();
-		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(index.newTerm( (String)key, (String)value ));
-		}
-		return null;
-	}
-
-	private Query booleanQuery(LuanTable queryTbl) {
-		if( !queryTbl.isList() )
-			return null;
-		List<Object> clauses = queryTbl.asList();
-		BooleanQuery query = new BooleanQuery();
-		for( Object obj : clauses ) {
-			if( !(obj instanceof LuanTable) )
-				return null;
-			LuanTable tbl = (LuanTable)obj;
-			if( !(tbl.isList() && tbl.length()==2) )
-				return null;
-			List<Object> list = tbl.asList();
-			Object obj0 = list.get(0);
-			Object obj1 = list.get(1);
-			if( !(obj0 instanceof String && obj1 instanceof LuanTable) )
-				return null;
-			BooleanClause.Occur occur;
-			try {
-				occur = BooleanClause.Occur.valueOf( ((String)obj0).toUpperCase() );
-			} catch(IllegalArgumentException e) {
-				return null;
-			}
-			Query subQuery = query( (LuanTable)obj1 );
-			if( subQuery == null )
-				return null;
-			query.add(subQuery,occur);
-		}
-		return query;
-	}
-
-	private Query query(LuanTable queryTbl) {
-		if( queryTbl.isEmpty() )
-			return null;
-		Query query;
-		query = termQuery(queryTbl);  if(query!=null) return query;
-		query = booleanQuery(queryTbl);  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;
-		field = index.fixFieldName(field);
-		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 String) )
-			throw luan.exception("invalid sort field"+pos+", order must be 'ascending' or 'descending'");
-		String order = (String)obj2;
-		boolean reverse;
-		if( order.equalsIgnoreCase("ascending") )
-			reverse = false;
-		else if( order.equalsIgnoreCase("descending") )
-			reverse = true;
-		else
-			throw luan.exception("invalid sort field"+pos+", order must be 'ascending' or 'descending'");
-		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);
-	}
-
 	private static final LuanFunction nothingFn = new LuanFunction() {
 		@Override public Object call(LuanState luan,Object[] args) {
 			return LuanFunction.NOTHING;
@@ -179,15 +72,7 @@
 		}
 	}
 
-	public Object[] search( final LuanState luan, LuanTable queryTbl, Object nObj, LuanTable sortTbl ) throws LuanException, IOException {
-		Query query;
-		if( queryTbl == null ) {
-			query = new MatchAllDocsQuery();
-		} else {
-			query = query(queryTbl);
-			if( query == null )
-				throw luan.exception("invalid query");
-		}
+	public Object[] search( final LuanState luan, Query query, Object nObj, Sort sort ) throws LuanException, IOException {
 		if( nObj instanceof LuanFunction ) {
 			final LuanFunction fn = (LuanFunction)nObj;
 			Collector col = new MyCollector() {
@@ -218,7 +103,7 @@
 			searcher.search(query,thcc);
 			return new Object[]{ nothingFn, 0, thcc.getTotalHits() };
 		}
-		TopDocs td = sortTbl==null ? searcher.search(query,n) : searcher.search(query,n,sort(luan,sortTbl));
+		TopDocs td = sort==null ? searcher.search(query,n) : searcher.search(query,n,sort);
 		final ScoreDoc[] scoreDocs = td.scoreDocs;
 		LuanFunction results = new LuanFunction() {
 			int i = 0;
@@ -244,7 +129,7 @@
 	LuanTable table() {
 		LuanTable tbl = Luan.newTable();
 		try {
-			add( tbl, "search", LuanState.class, LuanTable.class, Object.class, LuanTable.class );
+			add( tbl, "search", LuanState.class, Query.class, Object.class, Sort.class );
 		} catch(NoSuchMethodException e) {
 			throw new RuntimeException(e);
 		}
--- a/lucene/src/luan/modules/lucene/Web_search.luan	Wed Dec 03 02:26:19 2014 +0000
+++ b/lucene/src/luan/modules/lucene/Web_search.luan	Thu Dec 04 09:27:20 2014 +0000
@@ -27,11 +27,14 @@
 		<h1>Lucene Query</h1>
 		<form name="form0" method="post">
 			<p>
-				<span class="label">Query:</span> <input name="query" size="60" />
-				<div class="tip"><span class="label"></span> Query examples: { type = 'user' }</div>
+				<span class="label">Query:</span> <input name="query" size="60" value="Query.all_docs" />
+				<div class="tip"><span class="label"></span> Query examples: Query.term{ type = 'user' }</div>
 			</p>
 			<p><span class="label">Max Rows:</span> <input name="rows" value="20" maxlength="5" onkeypress="return event.charCode >= 48 && event.charCode <= 57" style="width:3em"/></p>
-			<p><span class="label">Sort:</span> <input name="sort" size="60" /></p>
+			<p>
+				<span class="label">Sort:</span> <input name="sort" size="60" />
+				<div class="tip"><span class="label"></span> Sort examples: Query.sort{{ field = 'id', type='int' }}</div>
+			</p>
 			<p><input type="submit" class="btn"/></p>
 		</form>
 		<script>document.form0.query.focus();</script>
@@ -48,8 +51,8 @@
 	</head>
 	<body>
 		<h1>Lucene Query Results</h1>
-			<p><span class="label">Query:</span> <b><%=repr(query)%></b></p>
-			<p><span class="label">Sort:</span> <b><%=repr(sort)%></b></p>
+			<p><span class="label">Query:</span> <b><%=query%></b></p>
+			<p><span class="label">Sort:</span> <b><%=sort%></b></p>
 			<table class="results">
 				<tr>
 					<th></th>
@@ -92,9 +95,9 @@
 			form()
 			return
 		end
-		local query = load(query_string,"<query>",{},true)()
+		local query = load(query_string,"<query>",{Query=index.Query},true)()
 		local rows = to_number(Http.request.parameters.rows)
-		local sort = load(Http.request.parameters.sort,"<sort>",{},true)()
+		local sort = load(Http.request.parameters.sort,"<sort>",{Query=index.Query},true)()
 		index.Searcher( function(searcher)
 			local results, length, total_hits = searcher.search(query,rows,sort)
 			local headers = {}