在Solr或ElasticSearch中使用根扩展器的邻近搜索短语(特别是websolr或bonsai.io)?

时间:2013-04-08 15:25:10

标签: solr elasticsearch wildcard proximity phrase

我正在尝试为大型项目选择搜索工具,我很想知道Solr或ElasticSearch是否支持此用例。

我的客户有兴趣进行相对复杂的布尔搜索。一个必须的搜索是能够使用根扩展器对短语进行邻近搜索。

例如,假设用户使用以下短语搜索文档:“可爱的狗被邪恶的浣熊攻击”

我希望用户能够在“dog”的5个单词中搜索“evil rac *”并返回带有上述句子的文档。理想情况下,查询看起来像:

(“邪恶的rac *”狗)〜5

到目前为止,我发现的唯一可以做我正在寻找的搜索工具是dtSearch。对dtSearch的查询将是“邪恶的rac *”w / 5狗,这很棒。我宁愿使用像Solr或ElasticSearch这样的开源工具(特别是诸如websolr或bonsai.io之类的托管解决方案)。任何建议都将非常感谢。

3 个答案:

答案 0 :(得分:2)

使用自定义查询解析器在技术上可行,但solr中的默认解析器,dismax等解析器似乎不支持此功能。关于这个问题有一个古老而未解决的问题:https://issues.apache.org/jira/browse/SOLR-1604

ElasticSearch仅支持使用JSON查询构建器,但看起来类似于短语的查询支持仅适用于“span_term”,这只是简单的单词。

有一些关于默认查询解析器在不久的将来更聪明的说法。

答案 1 :(得分:1)

绝对技术上可行,但在Lucene尚未得到支持。有一些未解决的问题需要支持Lucene中的“复杂短语”行为,这似乎是针对Lucene 4.3:

  

LUCENE-1486 - 默认QueryParser的扩展,它覆盖了对PhraseQueries的解析,以允许更复杂的语法,例如短语查询中的通配符。

我没有在他们的示例中看到您的具体查询结构,但这肯定比现在的更接近。

回顾一下:理论上可行,截至2013年4月和Lucene 4.2.1的语法不支持。

(给我的商业伙伴Kyle提示,帮助研究这个。)

答案 2 :(得分:0)

有可能但......

1)首先,检查http://wiki.apache.org/solr/SurroundQueryParserhttp://searchhub.org/2009/02/22/exploring-query-parsers/)是否有环绕查询解析器。这几乎就是你想要的。然而,人们声称(至少在某些地方)它支持短语查询,但事实并非如此。

2)所以你必须实现短语“邻近”。一个(令人讨厌的)黑客是更新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}“we defin”11w“descend”会匹配 “”” 我们定义一组按降序排序的单词 “”“