且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

solr入门之edismax权重排序使用之Java代码实现自定义权重

更新时间:2021-12-15 18:57:02

  1. package com.git.edismax;  
  2. import java.io.IOException;  
  3.   
  4. import org.apache.solr.client.solrj.SolrClient;  
  5. import org.apache.solr.client.solrj.SolrQuery;  
  6. import org.apache.solr.client.solrj.SolrServerException;  
  7. import org.apache.solr.client.solrj.SolrQuery.ORDER;  
  8. import org.apache.solr.client.solrj.impl.HttpSolrClient;  
  9. import org.apache.solr.client.solrj.response.QueryResponse;  
  10. import org.apache.solr.common.SolrDocument;  
  11. import org.apache.solr.common.SolrDocumentList;  
  12. import org.apache.solr.common.params.CommonParams;  
  13.   
  14. /** 
  15.  * 测试edismax的代码实现自定义权重排序股则 
  16.  * @author songqinghu 
  17.  * 
  18.  */  
  19. public class ScoreByEdismax {  
  20.   
  21.     private final static String baseURL = "http://localhost:8983/solr/dismax";  
  22.   
  23.   
  24.     public static void main(String[] args) throws Exception{  
  25.   
  26.         scoreBySum() ;  
  27.   
  28.         System.out.println("=====分割线==========");  
  29.   
  30.         scoreByProportion();  
  31.   
  32.     }  
  33.   
  34.     /** 
  35.      *  
  36.      * @描述:按照各个数值的比重来进行权重计算  count 10% point 45% hot 45%  --假设总分为100分 那么 分别最大分为 10 45 45 
  37.      * @return void 
  38.      * @exception 
  39.      * @createTime:2016年4月18日 
  40.      * @author: songqinghu 
  41.      * @throws IOException  
  42.      * @throws SolrServerException  
  43.      */  
  44.     public static void scoreByProportion() throws SolrServerException, IOException{  
  45.         //先查询出来三个字段中每个字段的最大值--编写好计算权重的公式---实际项目中应该还要加入是否存在的判断  
  46.   
  47.         long countMax = getMaxForField("count");  
  48.         long pointMax = getMaxForField("point");  
  49.         long hotMax = getMaxForField("hot");  
  50.   
  51.         String scoreMethod = "sum(product(div(count,"+countMax+"),10),product(div(point,"+pointMax+"),45),product(div(hot,"+hotMax+"),45))^1000000000";  
  52.   
  53.         SolrQuery query = new SolrQuery();  
  54.         query.set(CommonParams.Q, "国美*");  
  55.         query.set(CommonParams.FL,"id","name","count","point","hot","score");  
  56.   
  57.         query.set("defType","edismax");  
  58.   
  59.         query.set("bf", scoreMethod);  
  60.   
  61.   
  62.         QueryResponse response = getClient().query(query);  
  63.   
  64.         resultShow(response);  
  65.   
  66.     }  
  67.     /** 
  68.      * @描述:XXXXXXX 
  69.      * @return 
  70.      * @return long 
  71.      * @exception 
  72.      * @createTime:2016年4月18日 
  73.      * @author: songqinghu 
  74.      * @throws IOException  
  75.      * @throws SolrServerException  
  76.      */  
  77.     private static long getMaxForField(String fieldName) throws SolrServerException, IOException{  
  78.   
  79.         SolrQuery query = new  SolrQuery();  
  80.   
  81.         query.set(CommonParams.Q, "*:*");  
  82.         query.set(CommonParams.FL, fieldName);  
  83.         query.setSort(fieldName, ORDER.desc);  
  84.         query.setRows(1);  
  85.   
  86.         QueryResponse countResponse = getClient().query(query);  
  87.   
  88.         SolrDocument maxCount = countResponse.getResults().get(0);  
  89.   
  90.         long result = (long) maxCount.getFieldValue(fieldName);  
  91.         System.out.println(fieldName + ":" + result);  
  92.         return result;  
  93.     }  
  94.   
  95.   
  96.     /** 
  97.      *  
  98.      * @描述:按照 count point 和 hot 的 和的数量来进行权重计算 
  99.      * @return void 
  100.      * @exception 
  101.      * @createTime:2016年4月18日 
  102.      * @author: songqinghu 
  103.      * @throws IOException  
  104.      * @throws SolrServerException  
  105.      */  
  106.     public static  void  scoreBySum() throws SolrServerException, IOException{  
  107.   
  108.         SolrQuery query  = new SolrQuery();  
  109.   
  110.         query.set(CommonParams.Q, "国美*");  
  111.   
  112.         query.set(CommonParams.FL,"id","name","count","point","hot","score");  
  113.   
  114.         //开启edismax方式来进行自定义权重算法  
  115.         query.set("defType""edismax");  
  116.   
  117.         query.set("bf","sum(count,point,hot)^1000000000");  
  118.   
  119.   
  120.         QueryResponse response = getClient().query(query);  
  121.   
  122.         resultShow(response);  
  123.   
  124.     }  
  125.   
  126.     /** 
  127.      *  
  128.      * @描述:查询结果显示类 
  129.      * @param response 
  130.      * @return void 
  131.      * @exception 
  132.      * @createTime:2016年4月18日 
  133.      * @author: songqinghu 
  134.      */  
  135.     private static void resultShow(QueryResponse response){  
  136.   
  137.         int time = response.getQTime();  
  138.         System.out.println("响应时间:"+ time+"ms");  
  139.   
  140.         SolrDocumentList results = response.getResults();  
  141.         long numFound = results.getNumFound();  
  142.         System.out.println("总数量:"+numFound);  
  143.   
  144.         for (SolrDocument doc : results) {  
  145.   
  146.            System.out.println("id:"+ doc.getFieldValue("id").toString());  
  147.            System.out.println("name:"+ doc.getFieldValue("name").toString());  
  148.            System.out.println("count:"+ doc.getFieldValue("count").toString());  
  149.            System.out.println("point:"+ doc.getFieldValue("point").toString());  
  150.            System.out.println("hot:"+ doc.getFieldValue("hot").toString());  
  151.            System.out.println("score:"+ doc.getFieldValue("score").toString());  
  152.            System.out.println();  
  153.         }  
  154.     }  
  155.   
  156.   
  157.     /** 
  158.      *  
  159.      * @描述:获取单机版本的连接信息 
  160.      * @return 
  161.      * @return SolrClient 
  162.      * @exception 
  163.      * @createTime:2016年4月18日 
  164.      * @author: songqinghu 
  165.      */  
  166.     public static SolrClient getClient(){  
  167.   
  168.         SolrClient solrClient = new HttpSolrClient(baseURL);  
  169.   
  170.         return solrClient;  
  171.     }  
  172.   
  173.   
  174. }  
solr入门之edismax权重排序使用之Java代码实现自定义权重

执行结果:

响应时间:1ms
总数量:6
id:6
name:国美手机
count:2314
point:1123
hot:717
score:4154.0

id:1
name:国美集团
count:5
point:4
hot:3
score:12.0

id:5
name:国美美信
count:1
point:5
hot:4
score:10.0

id:2
name:国美电器
count:4
point:3
hot:2
score:9.0

id:4
name:国美金融
count:2
point:1
hot:5
score:8.0

id:3
name:国美在线
count:3
point:2
hot:1
score:6.0

=====分割线==========
count:2314
point:1123
hot:717
响应时间:2ms
总数量:6
id:6
name:国美手机
count:2314
point:1123
hot:717
score:100.0

id:5
name:国美美信
count:1
point:5
hot:4
score:0.45572376

id:1
name:国美集团
count:5
point:4
hot:3
score:0.3701771

id:4
name:国美金融
count:2
point:1
hot:5
score:0.36252183

id:2
name:国美电器
count:4
point:3
hot:2
score:0.26302284

id:3
name:国美在线
count:3
point:2
hot:1
score:0.15586855


权重计算分析:


权重影响参数设置表:
主查询权重*自定义权重

查询主条件比例 权重公式比例
solr计算
自己计算
^1
^100000000  
0.45572376
0.45572373506010969850068170504362
^1
^1000000000000
0.45572376

^0.0000000001
^1000000000000
0.45572376

实践得出 这里score的计算是两部分组成 一个是主查询的权重匹配值还有一个是自己设置的权重计算
可以使其中一个无限的趋近于一个最大值或者最小值但是不能使之为0
看到不去刻意的改变solr自身的两部分打分机制,其打分结果和理想的误差为0.025*0.000001 这个误差,一般情况应该都是能满足的,不影响结果的