Explorar o código

sort character when compareLength() returns PARALLEL in StringFieldComparatorSource

sunyj %!s(int64=8) %!d(string=hai) anos
pai
achega
06da941813

+ 51 - 2
src/main/java/com/uas/search/sort/StringFieldComparatorSource.java

@@ -1,5 +1,6 @@
 package com.uas.search.sort;
 
+import com.uas.search.util.CharUtils;
 import org.apache.lucene.search.FieldComparator;
 import org.apache.lucene.search.FieldComparatorSource;
 import org.springframework.util.StringUtils;
@@ -47,7 +48,8 @@ public class StringFieldComparatorSource extends FieldComparatorSource {
                             return BEHIND;
                         } else {
                             // 关键词在字符串中的位置相同时,比较字符串长度,长度较短,则排序靠前
-                            return compareLength(str1, str2);
+                            int compareLength = compareLength(str1, str2);
+                            return compareLength != PARALLEL ? compareLength : compareCharacter(str1, str2);
                         }
                     } else {
                         return AHEAD;
@@ -57,11 +59,15 @@ public class StringFieldComparatorSource extends FieldComparatorSource {
                         return BEHIND;
                     } else {
                         // 均不包含关键词时,比较字符串长度,长度较短,则排序靠前
-                        return compareLength(str1, str2);
+                        int compareLength = compareLength(str1, str2);
+                        return compareLength != PARALLEL ? compareLength : compareCharacter(str1, str2);
                     }
                 }
             }
 
+            /**
+             * 比较长度,长度较短,则排序靠前
+             */
             private int compareLength(String str1, String str2) {
                 int length1 = str1.length();
                 int length2 = str2.length();
@@ -73,6 +79,49 @@ public class StringFieldComparatorSource extends FieldComparatorSource {
                     return PARALLEL;
                 }
             }
+
+            /**
+             * 比较字母顺序,优先级:字母 > 其他字符(优先级视为相等) > 数字
+             */
+            private int compareCharacter(String str1, String str2) {
+                char[] array1 = str1.toLowerCase().toCharArray();
+                char[] array2 = str2.toLowerCase().toCharArray();
+                for (int i = 0; i < array1.length; i++) {
+                    char c1 = array1[i];
+                    char c2 = array2[i];
+                    // 字母 > 其他字符(优先级视为相等) > 数字
+                    if (CharUtils.isCharacter(c1)) {
+                        if (CharUtils.isCharacter(c2)) {
+                            // 均为字母,值越小优先级越高
+                            if (c1 < c2) {
+                                return AHEAD;
+                            } else if (c1 > c2) {
+                                return BEHIND;
+                            }
+                        } else {
+                            return AHEAD;
+                        }
+                    } else if (CharUtils.isNumber(c1)) {
+                        if (CharUtils.isNumber(c2)) {
+                            // 均为数字,数字越小优先级越高
+                            if (c1 > c2) {
+                                return BEHIND;
+                            } else if (c1 < c2) {
+                                return AHEAD;
+                            }
+                        } else {
+                            return BEHIND;
+                        }
+                    } else {
+                        if (CharUtils.isCharacter(c2)) {
+                            return BEHIND;
+                        } else if (CharUtils.isNumber(c2)) {
+                            return AHEAD;
+                        }
+                    }
+                }
+                return PARALLEL;
+            }
         };
     }
 }