1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
/* ------------------------------------ JavaOnTracks Thibaut Colar tcolar-jot AT colar DOT net Artistic Licence 2.0 http://www.javaontracks.net ------------------------------------ */ package net.jot.search.simpleindexer; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Hashtable; import java.util.List; /** * Default search sorter * Sorting results by score / hits * if all keywords are found in the page then you get maximum score(10/10) * each time one of the keyword is found in the page it counts as a "hit" * also finds the best line in the file(most keywords) can be use to show an abstract * @author tcolar */ public class JOTDefaultSearchSorter implements JOTSearchSorter { static JOTDefaultSearchComparator comp = new JOTDefaultSearchComparator(); public JOTSearchResult[] sortResults(JOTRawSearchResult[] rawResults) { Hashtable results = new Hashtable(); for (int i = 0; i != rawResults.length; i++) { JOTRawSearchResult result = rawResults[i]; String[] ids = result.getMatchingIds(); for (int j = 0; j != ids.length; j++) { Hashtable lineScores = new Hashtable(); String id = ids[j]; int score = 1; Integer[] lines = result.getResultsForId(id); int bestLine = 0; int bestLineScore = 0; for (int l = 0; l != lines.length; l++) { Integer lnScore = (Integer) lineScores.get(lines[l]); if (lnScore == null) { lnScore = new Integer(1); } lnScore = new Integer(lnScore.intValue() + 1); if (lnScore.intValue() > bestLineScore) { bestLine = lines[l].intValue(); bestLineScore = lnScore.intValue(); } lineScores.put(lines[l], lnScore); } int pts = lines.length; if (!results.containsKey(id)) { for (int k = i + 1; k < rawResults.length; k++) { if (rawResults[k].getResultsForId(id).length > 0) { score++; pts += rawResults[k].getResultsForId(id).length; Integer[] lines2 = rawResults[k].getResultsForId(id); for (int l = 0; l != lines2.length; l++) { Integer lnScore = (Integer) lineScores.get(lines2[l]); if (lnScore == null) { lnScore = new Integer(1); } lnScore = new Integer(lnScore.intValue() + 1); if (lnScore.intValue() > bestLineScore) { bestLine = lines2[l].intValue(); bestLineScore = lnScore.intValue(); } lineScores.put(lines2[l], lnScore); } } } score = (score * 10) / rawResults.length; JOTSearchResult entry = new JOTSearchResult(id, score, pts,bestLine,bestLineScore); results.put(id, entry); } } } List values = Arrays.asList(results.values().toArray()); //sort Collections.sort(values, comp); return (JOTSearchResult[]) values.toArray(new JOTSearchResult[0]); } /** * Default comparator to compare search results using score, hits */ static class JOTDefaultSearchComparator implements Comparator { public int compare(Object arg0, Object arg1) { JOTSearchResult result1 = (JOTSearchResult) arg0; JOTSearchResult result2 = (JOTSearchResult) arg1; if (result1.getScore() > result2.getScore()) { return -1; } else if (result1.getScore() < result2.getScore()) { return 1; } else { // same score, look at best line score if (result1.getBestLineScore() > result2.getBestLineScore()) { return -1; } else if (result1.getBestLineScore() < result2.getBestLineScore()) { return 1; } else { //same best line score, look at number of hits return result2.getHits().compareTo(result1.getHits()); } } } } }