2012-08-31 31 views
3

我們正在努力將Solr 3.6集成到電子商務網站。我們已索引數據&搜索表現非常好。爲暗示性/預測性自動完整搜索配置Solr

我們在如何使用預測性搜索/自動完成搜索建議方面遇到一些困難。也有興趣瞭解實現此功能的最佳實踐。

我們的目標是提供類似於http://www.amazon.com/的預測性搜索,但不知道如何使用Solr實現它。更具體地說,我想了解如何從Solr構建這些術語,還是由solr的其他外部處理?如何建立字典來提供這些建議?而且,對於某些領域,搜索應該提供搜索類別。嘗試在亞馬遜搜索框中輸入「xper」,你會注意到,除了xperia,xperia s,xperia p,它還列出了xperia s在手機&配件,這是一個類別。

使用自定義字典這將很難管理。或者可能我們不知道如何正確地做到這一點。期待您指導我們如何最好地利用solr來實現這種暗示性搜索。

+0

我想知道如果我的回答對您有所幫助? – javanna

+0

不,它幫助我理解可以做些什麼..但是我沒有明確知道應該做什麼,更具體地說怎麼做。 – Krunal

回答

6

我建議你幾個博客帖子的:

  • This一個是我寫的,這表明你是什麼出的現成的選項你在Solr的,什麼是你需要回答的問題爲了選擇其中一個
  • This一個它會顯示效果很好,但要求進行一些額外的工作,並且使用特定的Lucene索引(Solr的核心),爲特定目的
一個非常好的完整的解決方案
+0

你能幫我找出Solr的相關問題嗎? http://stackoverflow.com/questions/12453600/solr-suggester-lookup-class-for-predictive-search –

1

我使用了高亮的做法,因爲facet.prefix一個是大指數太重了,其他的人幾乎沒有或不清楚的(我是一個愚蠢的程序員)

所以,讓我們假設用戶只需鍵入 「aaa bbb ccc

我們的自動完成功能(Java/JavaScript的)將調用Solr的使用以下PARAMS

q="aaa bbb"~100 ...base query, all the typed words except the last 
fq=ccc* ...suggest word filter using last typed word 
hl=true 
hl.q=ccc* ...highlight word will be the one to suggest 
fl=NONE ...return empty docs in result tag 
hl.pre=### ...escape chars to locate highlight word in the response 
hl.post=### ...see above 

還可以控制建議與「rows」的數量和「hl.fragsize」參數

每個文檔中的亮點的話將是您的建議合適的人選與「aaa bbb」串

更多建議的話是突出顯示字前後的字眼,當然,你可以實現更多的過濾器來提取有效的字,避免重複,限制建議

如果有興趣,我可以給你一些例子...

EDITED:我們調用一個jsp(或Servlet)使作爲請求的Web應用程序內:關於方法

我請例子的部分假設通過的jquery給出的「自動完成」機制一些進一步的細節參數'q'是用戶輸入的單詞。

這是JSP

ByteArrayInputStream is=null; // Used to manage Solr response 
try{ 

    StringBuffer queryUrl=new StringBuffer('putHereTheUrlOfSolrServer'); 
    queryUrl.append("/select?wt=xml"); 
    String typedWords=request.getParameter("q"); 
    String base=""; 
    if(typedWords.indexOf(" ")<=0) { 
    // No space typed by user: the 'easy case' 
    queryUrl.append("&q=text:"); 
    queryUrl.append(URLEncoder.encode(typedWords+"*", "UTF-8")); 
    queryUrl.append("&hl.q=text:"+URLEncoder.encode(typedWords+"*", "UTF-8")); 
    } else { 
    // Space chars present 
    // we split the search in base phrase and last typed word 
    base=typedWords.substring(0,typedWords.lastIndexOf(" ")); 
    queryUrl.append("&q=text:"); 
    if(base.indexOf(" ")>0) 
     queryUrl.append("\""+URLEncoder.encode(base, "UTF-8")+"\"~1000"); 
    else 
     queryUrl.append(URLEncoder.encode(base, "UTF-8")); 

    typedWords=typedWords.substring(typedWords.lastIndexOf(" ")+1); 
    queryUrl.append("&fq=text:"+URLEncoder.encode(typedWords+"*", "UTF-8")); 
    queryUrl.append("&hl.q=text:"+URLEncoder.encode(typedWords+"*", "UTF-8")); 
} 

    // The additional parameters to control the solr response 
    queryUrl.append("&rows="+suggestPageSize); // Number of results returned, a parameter to control the number of suggestions 
    queryUrl.append("&fl=A_FIELD_NAME_THAT_DOES_NOT_EXIST"); // Interested only in highlights section, Solr return a 'light' answer 
    queryUrl.append("&start=0"); // Use only first page of results 
    queryUrl.append("&hl=true"); // Enable highlights feature 
    queryUrl.append("&hl.simple.pre=***"); // Use *** as 'highlight border' 
    queryUrl.append("&hl.simple.post=***"); // Use *** as 'highlight border' 
    queryUrl.append("&hl.fragsize="+suggestFragSize); // Another parameter to control the number of suggestions 
    queryUrl.append("&hl.fl=content,title"); // Look for result only in some fields 
    queryUrl.append("&facet=false"); // Disable facets 

    /* Omitted section: use a new URL(queryUrl.toString()) to get the solr response inside a byte array */ 

    is=new ByteArrayInputStream(solrResponseByteArray); 

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); 
    Document doc = dBuilder.parse(is); 
    XPathFactory xPathfactory = XPathFactory.newInstance(); 
    XPath xpath = xPathfactory.newXPath(); 
    XPathExpression expr = xpath.compile("//response/lst[@name=\"highlighting\"]/lst/arr[@name=\"content\"]/str"); 
    NodeList valueList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 

    Vector<String> suggestions=new Vector<String>(); 
    for (int j = 0; j < valueList.getLength(); ++j) { 
    Element value = (Element) valueList.item(j); 
    String[] result=value.getTextContent().split("\\*\\*\\*"); 
    for(int k=0;k<result.length;k++){ 
     String suggestedWord=result[k].toLowerCase(); 
     if((k%2)!=0){ 
      //Highlighted words management 
      if(suggestedWord.length()>=suggestedWord.length() && !suggestions.contains(suggestedWord)) 
       suggestions.add(suggestedWord); 
     }else{ 
      /* Words before/after highlighted words 
       we can put these words inside another vector 
       and use them if not enough suggestions */ 
     } 
    } 
    } 

    /* Finally we build a Json Answer to be managed by our jquery function */ 
    out.print(request.getParameter("json.wrf")+"({ \"suggestions\" : ["); 
    boolean firstSugg=true;  
    for(String suggestionW:suggestions) { 
    out.print((firstSugg?" ":" ,")); 
    out.print("{ \"suggest\" : \""); 
    if(base.length()>0) { 
     out.print(base); 
     out.print(" "); 
    } 
    out.print(suggestionW+"\" }"); 
    firstSugg=false; 
    } 
    out.print(" ]})"); 
}catch (Exception x) { 
    System.err.println("Exception during main process: " + x); 
    x.printStackTrace(); 
}finally{ 
    //Gracefully close streams// 
    try{is.close();}catch(Exception x){;} 
} 

希望能有幫助的代碼, 聶

+0

嗨,它是一個完全不同的方法。是的,請分享這些例子,這會非常有幫助。謝謝!! – Krunal