[solr]查询权重排序

来源:互联网 发布:淘宝网买东西怎么付款 编辑:程序博客网 时间:2024/05/22 16:08

Solr的defType有dismax/edismax两种,这两种的区别,可参见:http://blog.csdn.net/duck_genuine/article/details/8060026

 

下面示例用于演示如下场景:

有一网站,在用户查询的结果中,需要按这样排序:

  1. VIP的付费信息需要排在免费信息的前头
  2. 点击率越高越靠前
  3. 发布时间越晚的越靠前

 

这样的查询排序使用普通的查询结果的Order by是做不到的,必需使用solr的defType。

 

做法:

1、先看schema.xml的定义:

复制代码
<?xml version="1.0" ?><schema name="sample5" version="1.1">    <fieldtype name="string"  class="solr.StrField" sortMissingLast="true" omitNorms="true"/>    <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>    <fieldType name="tdate" class="solr.TrieDateField" precisionStep="6" positionIncrementGap="0"/>    <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>    <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/>    <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>    <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>    <fieldtype name="binary" class="solr.BinaryField"/>    <fieldType name="text_cn" class="solr.TextField">        <analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer" useSmart="false" />        <analyzer type="query" class="org.wltea.analyzer.lucene.IKAnalyzer" useSmart="true" />        <analyzer>            <tokenizer class="solr.KeywordTokenizerFactory"/>            <filter class="solr.LowerCaseFilterFactory" ignoreCase="true"/>        </analyzer>    </fieldType>        <!-- general -->    <fields>        <field name="id" type="long" indexed="true" stored="true" multiValued="false" required="true"/>        <field name="subject" type="text_cn" indexed="true" stored="true" />        <field name="content" type="text_cn" indexed="true" stored="true" />        <field name="regionId" type="int" indexed="true" stored="true" />        <field name="region" type="text_cn" indexed="true" stored="true" />        <field name="categoryId" type="int" indexed="true" stored="true" />        <field name="category" type="text_cn" indexed="true" stored="true" />        <field name="price" type="float" indexed="true" stored="true" />        <field name="createTime" type="tdate" indexed="true" stored="true" />        <field name="point" type="long" indexed="true" stored="true" />        <field name="vip" type="boolean" indexed="true" stored="true" />        <field name="_version_" type="long" indexed="true" stored="true"/>        <field name="searchText" type="text_cn" indexed="true" stored="false" multiValued="true" />    </fields>        <copyField source="subject" dest="searchText" />    <copyField source="content" dest="searchText" />    <copyField source="region" dest="searchText" />    <copyField source="category" dest="searchText" />         <!-- field to use to determine and enforce document uniqueness. -->     <uniqueKey>id</uniqueKey>     <!-- field for the QueryParser to use when an explicit fieldname is absent -->     <defaultSearchField>searchText</defaultSearchField>     <!-- SolrQueryParser configuration: defaultOperator="AND|OR" -->     <solrQueryParser defaultOperator="AND"/></schema>
复制代码

说明:

a)里头定义了一个copyField:searchText,此字段为:subject+content+region+category,并把这个字段设置为默认查询字段。意思是查询时,默认查询四个字段的内容。

b)把solrQueryParser设置为AND,事实上,大多情况下,我们是习惯使用AND为条件查询,而非OR

c)text_cn字段类型中的:useSmart

        <analyzer type="index" class="org.wltea.analyzer.lucene.IKAnalyzer" useSmart="false" />        <analyzer type="query" class="org.wltea.analyzer.lucene.IKAnalyzer" useSmart="true" />

意思是:useSmart =true ,分词器使用智能切分策略, =false则使用细粒度切分。详细,可下载IK分词器的源码看看。

 

2、加入一个查询Handler到solrconfig.xml的<config/>当中:

复制代码
    <requestHandler name="/browse" class="solr.SearchHandler" default="true" >        <lst name="defaults">            <str name="defType">edismax</str>            <str name="bf">                sum(linear(vip,1000,0),linear(sqrt(log(linear(point,1,2))),100,0),sqrt(log(ms(createTime))))            </str>            <!--<str name="pf">            searchText            </str>            <str name="qf">            subject^1 content^0.8            </str>-->        </lst>    </requestHandler>
复制代码

说明:

a)上面的default="true"意思为设置为默认的查询handler(记得把原standard中的default="true"删除掉)

b)见已经被注释的这段:

            <!--<str name="pf">            searchText            </str>            <str name="qf">            subject^1 content^0.8            </str>-->

这是简单的不使用bf的排序加权方式,可以用于应付简单的排序,具体pf/qf的使用,可以上网上搜搜应用。这里演示的功能相对“复杂”,不适用它。

c)见这句公式:

sum(linear(vip,1000,0),linear(sqrt(log(linear(point,1,2))),100,0),sqrt(log(ms(createTime))))

公式中的函数定义和意思,可以参考: 

官方文档:

http://wiki.apache.org/solr/FunctionQuery

中文说明:

http://mxsfengg.iteye.com/blog/352191

这里的函数意思是:

  • 如果是vip信息=值+1000,非vip信息=值+0
  • 点击率(point)的值范围为:50~500之间
  • 发布时间(createTime)值范围为:50以内

以上三个值相加得出最统权重分从高到低排序


0 0