Skip to content

Instantly share code, notes, and snippets.

@dav-rob
Created July 19, 2012 18:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dav-rob/3145858 to your computer and use it in GitHub Desktop.
Save dav-rob/3145858 to your computer and use it in GitHub Desktop.
Attempted Multi-Colum Sort Using Long return value.
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