第五章:自定义评分规则进行排序

1.  Solr内改变打分规则的几种形式

一、配置solr的solrconfig.xml中的edismax,来改变Boost打分规则
二、在solr的schema中添加一个字段,该字段专门用于排序
三、自定义评分规则

2.  自定义评分之重写ValueSourceParser

public class GardenSourceParser extends ValueSourceParser{

	public ValueSource parse(FunctionQParser fp) throws SyntaxError {
            String paramOne = fp.parseArg(); //获得第一个参数
	    String paramTow = fp.parseArg(); //<span style="white-space: pre-wrap; font-family: Arial, Helvetica, sans-serif;">获得第二个参数</span>
            return new GardenSortValueSource(<span style="white-space: pre-wrap; font-family: Arial, Helvetica, sans-serif;">paramOne</span><span style="white-space: pre-wrap; font-family: Arial, Helvetica, sans-serif;">, </span><span style="font-family: Arial, Helvetica, sans-serif; white-space: pre-wrap;">paramTow</span><span style="font-family: Arial, Helvetica, sans-serif; white-space: pre-wrap;">);</span><span style="white-space: pre-wrap; font-family: Arial, Helvetica, sans-serif;">
</span>	}

}

3.  自定义评分之重写ValueSource

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;

import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.docvalues.FloatDocValues;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.search.FunctionQParser;


public class GardenSortValueSource extends ValueSource {
	public String str;
	public String field;
	public FunctionQParser functionQParser;
	

	public GardenSortValueSource(String field,String str,FunctionQParser functionQParser) {
		this.str = str;
		this.field = field;
		this.functionQParser=functionQParser;
	}

	@Override
	public FunctionValues getValues(Map context,AtomicReaderContext readerContext) throws IOException {
		ValueSource nameField= getValueSource(this.functionQParser, "name");
		ValueSource simplePinyinField= getValueSource(this.functionQParser, "simplePinyin");
		ValueSource fullPinyinField= getValueSource(this.functionQParser, "fullPinyin");
		ValueSource searchFiledField= getValueSource(this.functionQParser, "searchFiled");
		ValueSource registerNameField= getValueSource(this.functionQParser, "registerName");
		
		final FunctionValues nameFieldVals =  nameField.getValues(context, readerContext);
		final FunctionValues simplePinyinFieldVals =  simplePinyinField.getValues(context, readerContext);
		final FunctionValues fullPinyinFieldVals =  fullPinyinField.getValues(context, readerContext);
		final FunctionValues searchFiledFieldVals =  searchFiledField.getValues(context, readerContext);
		final FunctionValues registerNameFieldVals =  registerNameField.getValues(context, readerContext);
		return new FloatDocValues(this) {
		      @Override
		      public float floatVal(int doc) {
		    	  
		    	  String name = nameFieldVals.strVal(doc); 
		    	  
		    	  float f = 10 - processNameWeights(name) - name.length() ;
		    	  
		    	  String simplePinyin = simplePinyinFieldVals.strVal(doc); 
		    	
		    	  String fullPinyin = fullPinyinFieldVals.strVal(doc); 
		    	  String searchFiled=searchFiledFieldVals.strVal(doc);
		    	  String registerName=registerNameFieldVals.strVal(doc);
		    	  
		    	  if(simplePinyin==null || "".equals(simplePinyin)){
		    		  return f;
		    	  }
		    	  
		    	  String[] temps=simplePinyin.split(",");
		    	  for (String string : temps) {
		    		  if(string.startsWith(str)){
		    			  if(string.equals(str)){
		    				  return 100f;
		    			  }
			    		  return 60f+f;
			    	  }
				  }		    	  
		    	  
		    	  if(name==null || "".equals(name)){
		    		  return f;
		    	  }		    	  
		    	  if(name.startsWith(str)){
	    			  if(name.equals(str)){
	    				  return 100f;
	    			  }
		    		  return 60f+f;
		    	  }
		    	  
		    	  if(fullPinyin==null || "".equals(fullPinyin)){
		    		  return f;
		    	  }
		    	  temps=fullPinyin.split(",");
		    	  for (String string : temps) {
		    		  if(string.startsWith(str)){
		    			  if(string.equals(str)){
		    				  return 100f;
		    			  }
			    		  return 60f+f;
			    	  }
				  }
		    	  
		    	  if(searchFiled==null || "".equals(searchFiled)){
		    		  return f;
		    	  }		    	  
		    	  if(searchFiled.startsWith(str)){
	    			  if(searchFiled.equals(str)){
	    				  return 100f;
	    			  }
		    		  return 60f+f;
		    	  }
		    	  
		    	  if(registerName==null || "".equals(registerName)){
		    		  return f;
		    	  }		    	  
		    	  if(registerName.startsWith(str)){
	    			  if(searchFiled.equals(str)){
	    				  return 100f;
	    			  }
		    		  return 60f+f;
		    	  }
		    	  
		          return f;
		      }
		      

		      @Override
		      public String toString(int doc) {
		        return name() + '(' + nameFieldVals.strVal(doc) + ')';
		      }
		    };
	}
	public static float processNameWeights(String name){
		float n1  = 0; 
		if(name==null || "".equals(name)){
			return n1;
		}
		char[] sc1 =  name.toCharArray();
		for(char c : sc1){
			int intval = (int)c;
			BigDecimal s1 = new BigDecimal(intval).movePointLeft((intval+"").length() -1);
			n1 += s1.floatValue();
		}
		return new BigDecimal(n1)
						.movePointLeft((new BigDecimal(n1).intValue()+"").length() - 1)
						.setScale(5,BigDecimal.ROUND_HALF_UP).floatValue();
	}


	@Override
	public boolean equals(Object o) {
		return true;
	}

	@Override
	public int hashCode() {
		return 0;
	}

	@Override
	public String description() {
		return null;
	}
	
	public String name() {
	      return "gardensort";
	}

	public ValueSource getValueSource(FunctionQParser fp, String arg) {
	    if (arg == null) {return null;}
	    SchemaField f = fp.getReq().getSchema().getField(arg);
	    return f.getType().getValueSource(f, fp);
	}

}

4.  SolrConfig.xml配置函数

<valueSourceParser name="gardensort"
                        class="GardenSourceParser" />

5.  Query参数中进行使用

solrQuery.setQuery("*:* AND _val_:\"gardensort(name,'dd')\"");


参考资料:http://blog.csdn.net/wgw335363240/article/details/37932475

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值