Reputation: 2569
Am using Lucene 4.7.2 version.
I have indexed some information and have create a UI to query on that interface. I create a BooleanQuery based on the user input,
example:
BooleanQuery bq = new BooleanQuery();
NumericRangeQuery<Integer> nrq = NumericRangeQuery.newIntRange("age", 20, 30, true, true);
bq.add(nrq, BooleanClause.Occur.MUST);
Term term = new Term("name", "einstein");
TermQuery termQuery = new TermQuery(term);
bq.add(termQuery, BooleanClause.Occur.MUST);
System.out.println(bq.toString());
This prints,
+age[20 TO 30] AND name:einstein
Lucene runs on a separate server and it expects Query object to perform search. As the Query or BooleanQuery is not serializable, am trying to convert above String query across and convert it to Query/Boolean object.
I found this idea of converting BooleanQuery.toString() to String and back to BooleanQuery but am not able to find any API to convert String query to Query type.
Upvotes: 4
Views: 5559
Reputation: 1004
use this:
String queryString="Name:alivaliolah";
Query QueryObj=new QueryParser("", perFieldAnalyzor).parse(queryString);
TopDocs topDocFounded = searcher.search(QueryObj, hitsPerPage);
Upvotes: 3
Reputation: 11
I asked a similar question on the java users group for lucene. What was recommended there were some Kryo libraries that worked for me: http://mail-archives.apache.org/mod_mbox/lucene-java-user/201603.mbox/browser. I didn't have much luck with simply casting the toString output to a Query either, but the Kyro libraries overcome some of the issues with No-argument constructors and other serialization limitations
Adapting from James McKinley's suggestion there to write:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Output output = new Output(baos);
Kryo kryo = new Kryo();
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
UnmodifiableCollectionsSerializer.registerSerializers(kryo);
kryo.register(Arrays.asList("").getClass(), new
ArraysAsListSerializer());
kryo.register(BooleanClause.class);
kryo.register(Query.class);
kryo.register(Occur.class);
kryo.register(ToParentBlockJoinQuery.class);
kryo.register(QueryBitSetProducer.class);
SynchronizedCollectionsSerializer.registerSerializers(kryo);
kryo.writeClassAndObject(output, (List<BooleanClause>)
builder.build().clauses());
output.close();
String outputString =
Base64.encodeBase64String(baos.toByteArray());
Reading:
String inputString = (String) in.readObject();
ByteArrayInputStream bais = new
ByteArrayInputStream(Base64.decodeBase64(inputString));
Input input = new Input(bais);
Kryo kryo = new Kryo();
kryo.setRegistrationRequired(false);
kryo.setInstantiatorStrategy(new StdInstantiatorStrategy());
UnmodifiableCollectionsSerializer.registerSerializers(kryo);
kryo.register(Arrays.asList("").getClass(), new
ArraysAsListSerializer());
kryo.register(BooleanClause.class);
kryo.register(Query.class);
kryo.register(Occur.class);
kryo.register(ToParentBlockJoinQuery.class);
kryo.register(QueryBitSetProducer.class);
SynchronizedCollectionsSerializer.registerSerializers(kryo);
@SuppressWarnings("unchecked")
List<BooleanClause> queryObject = (List<BooleanClause>)
kryo.readClassAndObject(input);
input.close();
builder = new BooleanQuery.Builder();
for (BooleanClause clause : queryObject) {
builder.add(clause);
}
I have my doubts about the need to register all the classes.
Upvotes: 0
Reputation: 26713
As I explained in the comment of linked question, just feed this String back to QueryParser
and you should get identical Query
objects back.
import org.apache.lucene.queryparser.classic.QueryParser;
...
String queryString = "+age[20 TO 30] AND name:einstein";
Query query = new QueryParser(Version.LUCENE_4_7, null, <yourAnalyzer>)
.parse(queryString);
Upvotes: 2