如何序列化Lucene Query或将查询转换为String并返回Query

时间:2014-09-15 05:45:12

标签: java solr lucene elasticsearch

使用的是Lucene 4.7.2版本。

我索引了一些信息,并创建了一个用于在该界面上查询的UI。我根据用户输入创建了一个BooleanQuery,

示例:

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());

打印,

+age[20 TO 30] AND name:einstein

Lucene在一个单独的服务器上运行,它希望Query对象执行搜索。由于Query或BooleanQuery不可序列化,我试图将上面的String查询转换为并将其转换为Query / Boolean对象。

我找到了this idea of converting BooleanQuery.toString() to String and back to BooleanQuery,但无法找到任何将String查询转换为查询类型的API。

3 个答案:

答案 0 :(得分:1)

正如我在链接问题的评论中所解释的那样,只需将此字符串反馈给QueryParser,您就应该返回相同的Query个对象。

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);

答案 1 :(得分:1)

使用它:

String queryString="Name:alivaliolah";
Query QueryObj=new QueryParser("", perFieldAnalyzor).parse(queryString);
TopDocs topDocFounded = searcher.search(QueryObj, hitsPerPage);

答案 2 :(得分:0)

我在lucene的java用户组中提出了类似的问题。推荐的是一些适合我的Kryo库:http://mail-archives.apache.org/mod_mbox/lucene-java-user/201603.mbox/browser。简单地将toString输出转换为Query也没有太多运气,但是Kyro库克服了无参数构造函数和其他序列化限制的一些问题

根据詹姆斯·麦金利的建议改编写作:

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());

读:

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);
}

我怀疑是否需要注册所有课程。