具有优先级的Groovy搜索条件

时间:2016-06-09 11:18:30

标签: groovy criteria sql-like

我有一个搜索框,在使用用户代码搜索时,我的预期结果是以给定关键字(keyword%)开头的用户代码,其余结果应为(%keyword%)。< / p>

Search with "TEST"

预期结果:

1. TEST1
2. TEST_ABC
3. TEST_QRS
...
11. ABC_TEST
12. BCTEST
像这样

但我得到的结果是:

1. ABC_TEST
2. BCTEST
...
11. TEST1
12. TEST_ABC
13. TEST_QRS

如何编写一个常规标准来获取具有这些优先级的搜索结果?

我目前的代码是:

def searchKeyword = PERCENT+keyword+PERCENT
def userList = User.createCriteria().list (max: max, offset: offset) {
  or {
    ilike "code", searchKeyword
    ilike "name", searchKeyword
  }
  order "code", "asc"
}

提前致谢。

2 个答案:

答案 0 :(得分:1)

我认为您无法使用GORM标准orderby语法实现所需的结果。您将不得不使用原始SQL查询groovy.sql.Sql

优先顺序结果的方法之一是使用CASE表达式,即对于Mysql的情况。例如,在您的情况下,要获得所需的结果,您可以使用原始查询,如

SELECT * FROM user WHERE name LIKE '%test%' or code LIKE '%test%' ORDER BY 
CASE WHEN name LIKE 'test%' THEN 1 WHEN code LIKE 'test%' THEN 2 ELSE 3 END;

在这种情况下,以'test%'开头的名称是第一优先,然后是代码,首先是'test%'< / strong>最后剩余的结果。 对于LIMIT参数 max offset ,您必须使用位置参数(?)来指定它们。

有关详情,请查看:

Grails GORM sort by CASE statement

Ordering by specific field value first

答案 1 :(得分:0)

我不确定,但也许这可以提供帮助:您可以使用比较器对用户的输出列表进行排序。比较器可以这样工作:

  1. 如果user1在关键字之前没有字母但user2具有,则user1&lt; user2,反之亦然
  2. 如果两个用户在关键字之前都有字母,则关键字之前字母数较少的用户的结果为-1。
  3. 如果两个用户在关键字后面都有字母,那么字母数较少的用户会有-1。
  4. 这样的事情:

    class UserComparator implements Comparator<User> {
    
        final String token
    
        UserComparator(String token){
            this.token = token
        }
    
        @Override
        int compare(User u1, User u2) {
            int u1Start = u1.name.indexOf(token)
            int u2Start = u2.name.indexOf(token)
    
            if (u1Start == 0 && u2Start != 0) return -1
            if (u2Start == 0 && u1Start != 0) return 1
    
            if (u1Start != 0 && u2Start != 0) return u1Start - u2Start
    
            return u1.name.size() - u2.name.size()
        }
    }