搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能)

转载自:http://blog.sina.com.cn/s/blog_4c925dca0102vga8.html 

本篇文章,阿堂将和大家分享sorl的高级应用自动补全功能。实际上,我们在在一些电商平台上购物就可以经常看到自动补全功能。

             如京东网上的截图所示
              搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能)


索引 
设想你想在你的在线商店中,给用户一些提示,比如商品的名称。假设我们的索引构建如下: 

<< field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/> 
<<field name="title" type="textik" indexed="true" stored="true" multiValued="false" /> 
<< field name="description" type="text" indexed="true" stored="true" multiValued="false" />


textik类型的定义为:
搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能)


配置 
开始前,首先考虑你要实现的功能:是要实现一个名字的提示,还是全名的提示。这都依赖于我们的选择,我们必须为需要引导的地方设置适当的域。 

单词提示 
在单词的情况下,我们使用的域也即一个token。在这种情况下,域名为title就足够了。但是,这属于一个词干,analysis的操作都在词干上,因此,我们最好换一个其他的类型。 

全名提示 
我们使用一个不同的域配置来定义全名提示--最好一个未被定义的域。但是我们不能使用基于类似string这种类型的域,基于这个原因,我们定义为一下的域: 

搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能)


textik类型的定义为: 

搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能)

为了不影响原有数据的格式,将原数据进行拷贝: 

搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能) 

如何使用 
为了使用这个数据,我们准备了一个简单的查询语句: 

q=*:* &facet=true &facet.field=FIELD &facet.mincount=1 &facet.prefix=USER_QUERY

需要替换的地方: 
   FIELD
:我们打算提供建议的域,在本例中域名为title title_auto 
   USER_QUERY
:用户输入的字符 

这里可以设置rows=0,这样可以只返回facet的结果,而没有查询结果。当然这不是必须的。 

查询的一个例子可以这样写: 

fl=id,name &rows=0 &q=*:* &facet=true &facet.field=name_auto &facet.mincount=1 &facet.prefix=你们

 

查询结果会返回这样的结果: 


<< response> 
<< lst name="responseHeader"> 
<< int name="status">0</</span>int> 
<< int name="QTime">0</</span>int> 
<< lst> 
<< result name="response" numFound="4" start="0"/> 
<< lst name="facet_counts"> 
<< lst name="facet_queries"/> 
<< lst name="facet_fields"> 
<< lst name="title_auto"> 
<< int name="你们">2</</span>int> 
<< int name="你们好">1</</span>int> 
<< int name="你们好吗">1</</span>int> 

<< lst> 
<< lst> 
<< lst name="facet_dates"/></</span>lst> 
<< response>

阿堂通过代码测试效果截图如下

 搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能)

搜索引擎之阿堂Solr学习笔记系列7(进阶篇:Solr的自动补全功能)

另外,阿堂附上了测试完整代码

public class SolrjCompleteContents {

   
    public static void main(String[] args) {       
       
        CommonsHttpSolrServer service=null;
       
        try {           
            service = new CommonsHttpSolrServer("http://localhost:9999/solr/");           
        } catch (MalformedURLException e1) {           
            e1.printStackTrace();           
        }  
       
        List list = new ArrayList();  
        //查询响应结果
        QueryResponse queryResponse = new QueryResponse();  
        //查询传输参数封装
        SolrQuery query = new SolrQuery();  
       
        try {  
           
               query.setFacet(true);  
               query.setRows(0);  
               query.setQuery("title:你们");  
               query.setFacetPrefix("你们"); 
               query.addFacetField("title_auto");
               query.setFacetLimit(20);
              
               System.out.println("query.toString() = "+query.toString());  
              
               queryResponse = service.query(query); 
               NamedListnl = queryResponse.getResponse(); 

               System.out.println("nl = "+nl);
              
               NamedListnl2 = (NamedList)nl.get("facet_counts");  
               NamedListnl3 = (NamedList)nl2.get("facet_fields");  
               NamedListnl4 = (NamedList)nl3.get("title_auto");  
              
               System.out.println("nl4.size() = "+nl4.size());  
              
               Iterator> it = nl4.iterator();
              
               while (it.hasNext()) {
                  
                   Entry entry = it.next();  
                   System.out.println(entry.getKey() + "____" + entry.getValue()); 
                  
               }
              
            } catch (Exception e) {
                e.printStackTrace();  
            } 
        }
    }

扩展功能 
    这里说一下他的一些常用的功能。 

    第一个是显示用户的一些额外的信息,比如当你选择某个提示词时,显示的结果的数量。这是一个很有意思的特性。

    另一个是使用facet.sort参数进行排序。这依赖于你的需求,我们可以按文档的数量排序(默认方式,设参数为true即可),或者按字母序排序(设为false)。 

    我们也可以通过设置facet.mincount来显示比指定的数量更多的提示词。 

    另外一个很好的特性是提示词不仅可以通过用户的类型获取,还可以通过其他的属性获取,这类似于类别。举个例子,我们想给用户展示家庭用品相关的商品,我们假设现在用户对DVD类型的商品并不感兴趣,这样我们添加一个参数: fq=department:homeApplications(假设有这个department)。通过这样的一个查询,你就不需要在所有的索引中匹配了,而是在我们选择的department里选择。 

结尾 
   跟其他方法一样,它有优点,也有缺点。优点就是易于使用、没有额外的组件依赖,并且能将结果约束在一个很小的范围内来更好的匹配用户的需求;另外一个很大的优点是它对每个提示词都附带了结果的统计。缺点就是需要添加额外的类型和字段;另外由于其facet的机制,对机器性能和load都非常消耗。

后记:

     实际上,上面阿堂演示分享的只是自动补全的基本功能,要想真正到电商平台的分类功能展示效果,还需要进行数据分类的详细设计,当然,这不是本篇文章讨论的范围,属于电商平台数据库的设计,要要分成多种数据表,如分类表,商品明细表,商品附加属性表及扩展表 等数据表,这样就可以通过自动补全功能展示非常丰富的效果了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值