使用弹簧数据进行不区分大小写的排序

case insensitive sort using spring data

如何使用 Spring-data Pageable 进行不区分大小写的排序?

我的存储库中有这个方法

1
2
3
4
public interface ItemRepository extends QueryDslPredicateExecutor<Item>{
    @Query("SELECT o FROM Item o WHERE o.status = ?1")
    Page<Item> findByStatus(Item.Status status, Pageable pageable);
}

我希望能够调用它:

1
itemRepository.findByStatus(Status.completed, new PageRequest(0, 10, Direction.ASC,"lower(name)")

注意属性字符串中的 lower 函数。这不起作用,因为 Spring-data 期望那里有一个属性。这将被翻译成类似:

1
SELECT o FROM Item o WHERE o.status = ?1 ORDER BY o.lower(name)

这当然行不通,因为对象上没有"较低"属性。

有没有办法让它工作?


Sort.Order.ignoreCase() 大约在 8 个月前被引入 spring-data-jpa,请看这里:

https://jira.springsource.org/browse/DATAJPA-296

https://github.com/kraymondksc/spring-data-jpa/commit/c3adce0bd36799d3754a5f4c61aee64982abd7e0

一旦你有了合适的 spring-data-jpa 版本(我想从 1.4 M1 开始,我就有 1.4.1),你可以这样写:

1
2
Sort.Order order = new Sort.Order(Sort.Direction.ASC,"name").ignoreCase();
itemRepository.findByStatus(Status.completed, new PageRequest(0, 10, new Sort(order));


以下是我用来排序的代码:

1
2
3
4
5
6
7
8
9
10
11
db.getCollection('employee').aggregate([
  {
    $project: {
         fieldToSortWith: { $toLower:"$lastName" },
         subject: 1
             }
 },
{
    $sort: { fieldToSortWith: 1 },
}
])

这就是你在Spring数据中的做法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DBCollection coll = mongoTemplate.getCollection("employee");
       List<DBObject> pipe = new ArrayList<>();
        DBObject prjflds = new BasicDBObject();
        prjflds.put("id", 1);
        prjflds.put("firstName", 2);
        prjflds.put("lastName", new BasicDBObject("$toLower","$lastName"));
        DBObject project = new BasicDBObject();
        project.put("$project", prjflds);
        pipe.add(project);
        DBObject sort = new BasicDBObject();
        sort.put("$sort", new BasicDBObject("lastName", 1));
        pipe.add(sort);
        BasicDBObject skip = new BasicDBObject("$skip", searchCriteria.getCurrentPage() * searchCriteria.getPageSize());
        BasicDBObject limit = new BasicDBObject("$limit", searchCriteria.getPageSize());
        pipe.add(skip);
        pipe.add(limit);
        BasicDBObject employeeRoleFilter = new BasicDBObject("$match", new BasicDBObject("employeeRoles", new BasicDBObject("$in", searchCriteria.getEmployeeRolesNames())));
        pipe.add(employeeRoleFilter);
        BasicDBObject employeeStatusFilter = new BasicDBObject("$match", new BasicDBObject("active", new BasicDBObject("$eq", Boolean.valueOf(searchCriteria.getEmployeeStatus()))));
        pipe.add(employeeStatusFilter);
        searchCriteria.isEmployeeNameSearchIndicator());
        pipe.add(searchTextFilter);
        coll.aggregate(pipe).results();

之后,您将获得需要在您的域中转换的本机 BasicDBObjects。如果您需要任何帮助,请告知此代码是混乱的。