我正在尝试为一个大型项目选择一个搜索工具,我很想知道这个用例是否被Solr或ElasticSearch支持。
我的客户对执行相对复杂的布尔搜索感兴趣。一个必须的搜索是对带有根扩展符的短语进行接近搜索的能力。
例如,假设用户搜索包含以下短语的文档:"可爱的狗被邪恶的浣熊袭击了"
我希望用户能够在"狗"的5个单词内搜索"邪恶的rac*",并返回具有上述句子的文档。理想情况下,查询应该是这样的:
("evil rac*" dog)~5
到目前为止,我发现唯一的搜索工具,可以做我正在寻找的是dtSearch。对dtSearch的查询将是"evil rac*"w/5 dog,这很好。我宁愿使用像Solr或ElasticSearch这样的开源工具(尤其是像websolr或bonsaio这样的托管解决方案)。如有任何建议,我将不胜感激。
使用自定义查询解析器在技术上当然可以做到这一点,但是solr中的默认、dismax等解析器似乎不支持这一点。这是一个老的未解决的问题:https://issues.apache.org/jira/browse/SOLR-1604.
ElasticSearch只支持JSON查询构建器,但似乎短语类查询支持只支持"span_term",这只是简单的单词。
有一些关于默认查询解析器在不久的将来会更聪明的讨论。
技术上肯定是可能的,但是Lucene还不支持。在Lucene中有一些支持"复杂短语"行为的开放问题,这似乎是针对Lucene 4.3的:
LUCENE-1486 -默认QueryParser的扩展,覆盖了PhraseQueries的解析,以允许更复杂的语法,例如短语查询中的通配符。
我没有在他们的例子中看到你的特定查询结构,但这绝对比今天可用的更接近。
概括一下:理论上可行,2013年4月和Lucene 4.2.1的语法不支持。
(感谢我的商业伙伴Kyle帮助我研究这个问题)
这是可能的,但是…
1)首先,检查http://wiki.apache.org/solr/SurroundQueryParser (http://searchhub.org/2009/02/22/exploring-query-parsers/)中的环绕查询解析器。这几乎就是你想要的。然而,人们声称(至少在某些地方)它支持短语查询,但事实并非如此。
2)所以你必须实现短语接近。一个(讨厌的)hack是更新DistanceQuery::getSpanNearQuery(在lucene/queryparser/…/DistanceQuery.java中的solr 4.2.1第78行)
while (sqi.hasNext()) {
SpanNearClauseFactory sncf = new SpanNearClauseFactory(reader, fieldName, qf);
// HACK starts here
DistanceSubQuery dsq = ((DistanceSubQuery)sqi.next());
try {
if ( ((SrndTermQuery)dsq).getTermText().contains( " " ) ) {
String term_text = ((SrndTermQuery)dsq).getTermText();
String[] tokens = term_text.split("\s+");
SpanQuery[] span_queries = new SpanQuery[tokens.length];
for ( int i = 0; i < tokens.length; ++i ) {
span_queries[i] = new SpanTermQuery( new Term(fieldName, tokens[i]) );
}
spanClauses[qi] = new SpanNearQuery( span_queries, 0, true);
qi++;
continue;
}
}catch( Exception ex ){
}
// HACK ends here
dsq.addSpanQueries(sncf);
3)并且要注意,没有对数据进行预处理,所以如果你使用词干提取,你必须搜索准确的单词,例如,选择?q={!Surround df=text}"我们定义" 11w "将会匹配""我们定义了一组按降序排序的单词" " "