Created
July 19, 2012 18:31
-
-
Save dav-rob/3145858 to your computer and use it in GitHub Desktop.
Attempted Multi-Colum Sort Using Long return value.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cs.cts.crm.elasticsearch.util; | |
import java.util.List; | |
import java.util.Map; | |
import org.apache.commons.logging.Log; | |
import org.apache.commons.logging.LogFactory; | |
import org.elasticsearch.script.AbstractLongSearchScript; | |
import org.elasticsearch.script.ExecutableScript; | |
import org.elasticsearch.script.NativeScriptFactory; | |
/** | |
* This class is run in isolation on the ElasticSearch Server, so can have no dependencies on other classes in CMT. | |
* | |
* @author drober20 | |
* | |
*/ | |
public class CustomColumnSorterFactory implements NativeScriptFactory{ | |
private final static Log LOG = LogFactory.getLog(CustomColumnSorterFactory.class); | |
@Override | |
public ExecutableScript newScript(Map<String, Object> params) { | |
LOG.info("Last string long value = " + last); | |
return new ColumnSortScript(params); | |
} | |
//private static String lastString = "\u007F";// 8 bit last string | |
//"\uffff";// 16 bit last string | |
/** | |
* This method is to allow us to sort on more then one letter in a string when we only have the | |
* option of returning a single Long (or Int or Long) value from 'sortValue' method for each | |
* document, rather than being able to compare one document with another. | |
* | |
* @param custAttrValue | |
* @return | |
*/ | |
private static Long getFirstThreeLettersLongValue(String custAttrValue, int order) { | |
if (custAttrValue.length() == 0){ | |
throw new IllegalStateException("Null or empty strings should be initialised to 'z'"); | |
} | |
long threeCharValue = 0; | |
int sortCharLength = custAttrValue.length() < 3 ? custAttrValue.length() : 3; | |
for (int i = 0; i < sortCharLength;i++ ){ | |
long singleCharValue = custAttrValue.charAt(i); | |
// force 8 bit letters | |
// may be able to stop this by returning longs from 'sortValue' method. | |
if (singleCharValue > 127){ | |
singleCharValue = 127; | |
} | |
if (i==0 && order == 0){ | |
// i.e. threeCharValue = threeCharValue + (char value)*(2^16) | |
threeCharValue += singleCharValue* Math.pow(2, 40); | |
} else if (i==0 && order == 1){ | |
// i.e. threeCharValue = threeCharValue + (char value)*(2^-24) | |
threeCharValue += singleCharValue* Math.pow(2, 16); // | |
} | |
else if (i == 1 && order == 0) { | |
threeCharValue += singleCharValue* Math.pow(2, 32); | |
} else if (i == 1 && order == 1){ | |
threeCharValue += singleCharValue* Math.pow(2, 8); | |
} | |
/*else if (i == 2 && order == 0){ | |
threeCharValue += singleCharValue* Math.pow(2, 24); | |
} else if (i == 2 && order == 1){ | |
threeCharValue += singleCharValue* Math.pow(2, 0); | |
}*/ | |
} | |
return threeCharValue; | |
} | |
protected static Long last = (long)(Long.MAX_VALUE - 16); | |
//getFirstThreeLettersLongValue(lastString); | |
private static Long getAsLong(String custAttValue1, int order) { | |
try { | |
long theLong = Long.valueOf(custAttValue1); | |
//if (order == 0){ | |
return theLong; //* Math.pow(2, 24); | |
/*} else { | |
long smallLong = theLong * Math.pow(2, -24); | |
return smallLong; | |
}*/ | |
}catch (NumberFormatException nfe){ | |
return null; | |
} | |
} | |
public static Long getScore(List<Map> custColsMapList, String indexFieldName, boolean isASC, int order){ | |
String custAttrValue = getCustomAttrValue(custColsMapList, indexFieldName); | |
Long score = getLongScore(custAttrValue, isASC, order); | |
String logDesc = String.format("Cust Column Value [%s], Score[%d]", custAttrValue, score); | |
LOG.info(logDesc); | |
return score; | |
} | |
public static String getCustomAttrValue(final List<Map> custColsMapList, String indexFieldName) { | |
String custAttValue = null; | |
for (Map custColsMap : custColsMapList) { | |
String ccId = (String)custColsMap.get("ccId"); | |
if (ccId.equals(indexFieldName)){ | |
//LOG.info("ccId = " + ccId ); | |
Object value = custColsMap.get("value"); | |
//LOG.info("value = " + value ); | |
if (value != null){ | |
return value.toString(); | |
} | |
} | |
} | |
return custAttValue; | |
} | |
public static Long getLongScore(String custAttrValue, boolean isASC, int order) { | |
boolean isEmpty = custAttrValue == null || custAttrValue.trim().equals(""); | |
if (isEmpty){ | |
return isASC ? last : 0; | |
} | |
Long longValue = getAsLong(custAttrValue, order); | |
if (longValue == null){ | |
longValue = getFirstThreeLettersLongValue(custAttrValue.toUpperCase(), order); | |
} else { | |
// reduce the numbers value to give the letters a bit more room in the long range. | |
// tried doing longValue = longValue - 1000000 to give the numbers more room | |
// below the letters, but it doesn't work. | |
longValue = longValue; | |
} | |
return longValue; | |
} | |
private static Long getScoreForDirection(boolean isASC, Long score) { | |
if (isASC){ | |
score = 0- score; | |
} | |
return score; | |
} | |
static class ColumnSortScript extends AbstractLongSearchScript { | |
private Map<String, Object> params; | |
public ColumnSortScript(Map<String, Object> params) { | |
this.params = params; | |
} | |
@Override | |
public long runAsLong() { | |
// TODO Auto-generated method stub | |
return doRunAsLong(); | |
} | |
public long doRunAsLong() { | |
try { | |
long score = 0; | |
if (params.get("isCustomColumn") != null){ | |
score = getCustomColumnLongValue("sortDirection", "indexFieldName", 0); | |
} else { | |
score = getNormalColumnLongValue("sortDirection", "indexFieldName"); | |
} | |
//make first sort score into its' equivalent long score | |
long totalScore = score; | |
long score1 = 0; | |
if (params.get("isCustomColumn1") != null){ | |
score1 = getCustomColumnLongValue("sortDirection1", "indexFieldName1", 1); | |
} else { | |
score1 = getNormalColumnLongValue("sortDirection1", "indexFieldName1"); | |
} | |
totalScore += score1; | |
String logDesc = String.format("score[%d], score1[%d], totalScore[%d]", score, score1, totalScore); | |
LOG.info(logDesc); | |
return totalScore; | |
} catch (Exception e) { | |
LOG.error("Unexpected error sorting custom columns.", e); | |
return 0; | |
} | |
} | |
private long getNormalColumnLongValue(String sortDirectionKey, String indexFieldNameKey) { | |
// TODO Auto-generated method stub | |
return 0; | |
} | |
private Long getCustomColumnLongValue(String sortDirectionKey, String indexFieldNameKey, int order) { | |
String sortDirection = (String)params.get(sortDirectionKey); | |
boolean isASC = sortDirection == null || (sortDirection != null && !sortDirection.toUpperCase().trim().equals("DESC")); | |
Object customColsMapList = source().get("customColumns"); | |
//LOG.info(" Source = " + customColsMapList.getClass()); | |
if (customColsMapList == null ){ | |
long defaultReturn = defaultReturn(isASC); | |
//LOG.info("Default return = " + defaultReturn); | |
return defaultReturn; | |
//return getScoreForDirection(isASC, last); | |
} | |
List<Map> custColsMapList = (List<Map>) customColsMapList; | |
if (custColsMapList == null || custColsMapList.size() == 0){ | |
long defaultReturn = defaultReturn(isASC); | |
//LOG.info("Default return = " + defaultReturn); | |
return defaultReturn; | |
} | |
String indexFieldName = (String)params.get(indexFieldNameKey); | |
Long score = getScore(custColsMapList, indexFieldName, isASC, order); | |
score = getScoreForDirection(isASC, score); | |
return score; | |
} | |
private long defaultReturn(boolean isASC) { | |
if (isASC){ | |
return 0 - last; | |
} else { | |
return 0; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment