Use double instead of int for score calculation, weigh position of hit more.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 15 Apr 2011 04:19:44 +0000 (06:19 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 15 Apr 2011 04:19:44 +0000 (06:19 +0200)
src/main/java/net/pterodactylus/sone/web/SearchPage.java

index 1d1aa36..903975d 100644 (file)
@@ -35,6 +35,7 @@ import net.pterodactylus.util.collection.Converters;
 import net.pterodactylus.util.collection.Pagination;
 import net.pterodactylus.util.filter.Filter;
 import net.pterodactylus.util.filter.Filters;
+import net.pterodactylus.util.logging.Logging;
 import net.pterodactylus.util.number.Numbers;
 import net.pterodactylus.util.template.Template;
 import net.pterodactylus.util.template.TemplateContext;
@@ -137,7 +138,7 @@ public class SearchPage extends SoneTemplatePage {
                Set<Hit<T>> hits = new HashSet<Hit<T>>();
                for (T object : objects) {
                        String objectString = stringGenerator.generateString(object);
-                       int score = calculateScore(phrases, objectString);
+                       double score = calculateScore(phrases, objectString);
                        hits.add(new Hit<T>(object, score));
                }
                return hits;
@@ -185,9 +186,9 @@ public class SearchPage extends SoneTemplatePage {
         *            The expression to search
         * @return The score of the expression
         */
-       private int calculateScore(List<Phrase> phrases, String expression) {
-               int optionalHits = 0;
-               int requiredHits = 0;
+       private double calculateScore(List<Phrase> phrases, String expression) {
+               double optionalHits = 0;
+               double requiredHits = 0;
                int forbiddenHits = 0;
                int requiredPhrases = 0;
                for (Phrase phrase : phrases) {
@@ -197,11 +198,13 @@ public class SearchPage extends SoneTemplatePage {
                        }
                        int matches = 0;
                        int index = 0;
+                       double score = 0;
                        while (index < expression.length()) {
                                int position = expression.toLowerCase().indexOf(phraseString, index);
                                if (position == -1) {
                                        break;
                                }
+                               score += Math.pow(1 - position / (double) expression.length(), 2);
                                index = position + phraseString.length();
                                ++matches;
                        }
@@ -209,10 +212,10 @@ public class SearchPage extends SoneTemplatePage {
                                continue;
                        }
                        if (phrase.getOptionality() == Phrase.Optionality.REQUIRED) {
-                               requiredHits += matches;
+                               requiredHits += score;
                        }
                        if (phrase.getOptionality() == Phrase.Optionality.OPTIONAL) {
-                               optionalHits += matches;
+                               optionalHits += score;
                        }
                        if (phrase.getOptionality() == Phrase.Optionality.FORBIDDEN) {
                                forbiddenHits += matches;
@@ -418,7 +421,7 @@ public class SearchPage extends SoneTemplatePage {
 
                        @Override
                        public int compare(Hit<?> leftHit, Hit<?> rightHit) {
-                               return rightHit.getScore() - leftHit.getScore();
+                               return (rightHit.getScore() < leftHit.getScore()) ? -1 : ((rightHit.getScore() > leftHit.getScore()) ? 1 : 0);
                        }
 
                };
@@ -427,7 +430,7 @@ public class SearchPage extends SoneTemplatePage {
                private final T object;
 
                /** The score of the object. */
-               private final int score;
+               private final double score;
 
                /**
                 * Creates a new hit.
@@ -437,7 +440,7 @@ public class SearchPage extends SoneTemplatePage {
                 * @param score
                 *            The score of the object
                 */
-               public Hit(T object, int score) {
+               public Hit(T object, double score) {
                        this.object = object;
                        this.score = score;
                }
@@ -456,7 +459,7 @@ public class SearchPage extends SoneTemplatePage {
                 *
                 * @return The score of the object
                 */
-               public int getScore() {
+               public double getScore() {
                        return score;
                }