changeset 1771:c62324841dfb

improve NumberFieldParser and add key map lucene query
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 25 Jun 2023 15:05:09 -0600
parents 6c01d54edcac
children f7b90d9a4639
files src/goodjava/lucene/api/LuceneUtils.java src/goodjava/lucene/queryparser/NumberFieldParser.java src/luan/modules/lucene/Lucene.luan src/luan/modules/lucene/LuceneIndex.java src/luan/modules/lucene/SupplementingConfig.java
diffstat 5 files changed, 59 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/goodjava/lucene/api/LuceneUtils.java	Thu Jun 15 17:55:47 2023 -0600
+++ b/src/goodjava/lucene/api/LuceneUtils.java	Sun Jun 25 15:05:09 2023 -0600
@@ -8,7 +8,7 @@
 import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.NumericUtils;
+import goodjava.lucene.queryparser.NumberFieldParser;
 
 
 public final class LuceneUtils {
@@ -56,13 +56,9 @@
 		if( value instanceof String ) {
 			return new Term(name,(String)value);
 		} else if( value instanceof Long ) {
-			BytesRef br = new BytesRef();
-			NumericUtils.longToPrefixCoded((Long)value,0,br);
-			return new Term(name,br);
+			return NumberFieldParser.term(name,(Long)value);
 		} else if( value instanceof Integer ) {
-			BytesRef br = new BytesRef();
-			NumericUtils.intToPrefixCoded((Integer)value,0,br);
-			return new Term(name,br);
+			return NumberFieldParser.term(name,(Integer)value);
 		} else
 			throw new RuntimeException("invalid value type "+value.getClass()+"' for term '"+name+"'");
 	}
--- a/src/goodjava/lucene/queryparser/NumberFieldParser.java	Thu Jun 15 17:55:47 2023 -0600
+++ b/src/goodjava/lucene/queryparser/NumberFieldParser.java	Sun Jun 25 15:05:09 2023 -0600
@@ -4,8 +4,11 @@
 import org.apache.lucene.search.NumericRangeQuery;
 import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.PrefixQuery;
+import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.util.BytesRef;
 import goodjava.parser.ParseException;
+import org.apache.lucene.util.NumericUtils;
 
 
 public abstract class NumberFieldParser implements FieldParser {
@@ -13,7 +16,15 @@
 	@Override public final Query getQuery(GoodQueryParser qp,String field,String query) throws ParseException {
 		if( query.equals("*") )
 			return new PrefixQuery(new Term(field,""));
-		return getRangeQuery(qp,field,query,query,true,true);
+		try {
+			return getQuery(field,query);
+		} catch(NumberFormatException e) {
+			throw qp.exception(e);
+		}
+	}
+
+	protected Query getQuery(String field,String query) {
+		return getRangeQuery(field,query,query,true,true);
 	}
 
 	@Override public final Query getRangeQuery(GoodQueryParser qp,String field,String minQuery,String maxQuery,boolean includeMin,boolean includeMax) throws ParseException {
@@ -35,6 +46,11 @@
 
 	public static final FieldParser INT = new NumberFieldParser() {
 
+		@Override protected Query getQuery(String field,String query) {
+			int n = Integer.valueOf(query);
+			return new TermQuery( term(field,n) );
+		}
+
 		@Override protected Query getRangeQuery(String field,String minQuery,String maxQuery,boolean includeMin,boolean includeMax) {
 			Integer min = minQuery.equals("*") ? null : Integer.valueOf(minQuery);
 			Integer max = maxQuery.equals("*") ? null : Integer.valueOf(maxQuery);
@@ -48,6 +64,11 @@
 
 	public static final FieldParser LONG = new NumberFieldParser() {
 
+		@Override protected Query getQuery(String field,String query) {
+			long n = Long.valueOf(query);
+			return new TermQuery( term(field,n) );
+		}
+
 		@Override protected Query getRangeQuery(String field,String minQuery,String maxQuery,boolean includeMin,boolean includeMax) {
 			Long min = minQuery.equals("*") ? null : Long.valueOf(minQuery);
 			Long max = maxQuery.equals("*") ? null : Long.valueOf(maxQuery);
@@ -85,4 +106,16 @@
 		}
 	};
 
+	public static Term term(String name,int value) {
+		BytesRef br = new BytesRef();
+		NumericUtils.intToPrefixCoded(value,0,br);
+		return new Term(name,br);
+	}
+
+	public static Term term(String name,long value) {
+		BytesRef br = new BytesRef();
+		NumericUtils.longToPrefixCoded(value,0,br);
+		return new Term(name,br);
+	}
+
 }
--- a/src/luan/modules/lucene/Lucene.luan	Thu Jun 15 17:55:47 2023 -0600
+++ b/src/luan/modules/lucene/Lucene.luan	Sun Jun 25 15:05:09 2023 -0600
@@ -8,6 +8,7 @@
 local get_local_cloned = Luan.get_local_cloned
 local set_local_cloned = Luan.set_local_cloned
 local pairs_local_cloned = Luan.pairs_local_cloned
+local stringify = Luan.stringify or error()
 local Boot = require "luan:Boot.luan"
 local Html = require "luan:Html.luan"
 local Number = require "luan:Number.luan"
@@ -167,7 +168,7 @@
 			doc = doc_fn()
 		end
 		local total_hits = index.advanced_search(query,fn,1)
-		total_hits <= 1 or error("found "..total_hits.." documents for query: "..query)
+		total_hits <= 1 or error("found "..total_hits.." documents for query: "..stringify(query))
 		return doc
 	end
 
--- a/src/luan/modules/lucene/LuceneIndex.java	Thu Jun 15 17:55:47 2023 -0600
+++ b/src/luan/modules/lucene/LuceneIndex.java	Sun Jun 25 15:05:09 2023 -0600
@@ -27,6 +27,9 @@
 import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.TermQuery;
 import org.apache.lucene.search.TopDocs;
 import org.apache.lucene.search.Sort;
 import org.apache.lucene.search.SortField;
@@ -198,12 +201,6 @@
 		}
 	}
 
-	private static Term term(String key,long value) {
-		BytesRef br = new BytesRef();
-		NumericUtils.longToPrefixCoded(value,0,br);
-		return new Term(key,br);
-	}
-
 	public void delete(String queryStr)
 		throws IOException, ParseException, LuanException
 	{
@@ -460,11 +457,24 @@
 		close(openSearcher());
 	}
 
-	public int advanced_search( final Luan luan, String queryStr, LuanFunction fn, Integer n, String sortStr )
+	public int advanced_search( final Luan luan, Object queryStr, LuanFunction fn, Integer n, String sortStr )
 		throws LuanException, IOException, ParseException
 	{
-		Utils.checkNotNull(queryStr);
-		Query query = GoodQueryParser.parseQuery(mfp,queryStr);
+		Query query;
+		if( queryStr instanceof String ) {
+			query = GoodQueryParser.parseQuery(mfp,(String)queryStr);
+		} else if( queryStr instanceof LuanTable ) {
+			LuanTable t = (LuanTable)queryStr;
+			BooleanQuery bq = new BooleanQuery();
+			for( Map.Entry<Object,Object> entry : t.rawIterable() ) {
+				String name = (String)entry.getKey();
+				Object value = entry.getValue();
+				Query q = new TermQuery( LuceneUtils.term(name,value) );
+				bq.add( q, BooleanClause.Occur.MUST );
+			}
+			query = bq;
+		} else
+			throw new LuanException("query must be string or table");
 		IndexSearcher searcher = threadLocalSearcher.get();
 		boolean inTransaction = searcher != null;
 		if( !inTransaction )
--- a/src/luan/modules/lucene/SupplementingConfig.java	Thu Jun 15 17:55:47 2023 -0600
+++ b/src/luan/modules/lucene/SupplementingConfig.java	Sun Jun 25 15:05:09 2023 -0600
@@ -69,7 +69,7 @@
 		Map<String,Object> map = new LinkedHashMap<String,Object>();
 		for( Map.Entry<Object,Object> entry : table.rawIterable() ) {
 			String name = (String)entry.getKey();
-			Object value  = entry.getValue();
+			Object value = entry.getValue();
 			if( value instanceof LuanTable ) {
 				LuanTable list = (LuanTable)value;
 				if( !list.isList() )