Hibernate Grails with Criteria fetch,或按预定顺序进行排序的快速方法

Hibernate Grails with Criteria fetch,或按预定顺序进行排序的快速方法,hibernate,grails,criteria,hibernate-criteria,Hibernate,Grails,Criteria,Hibernate Criteria,数据库函数返回特定半径内所有事件的id,按距离排序 之后,为了保持性能,我急切地将必要的集合加载到中,使用条件如下: def events = Event.withCriteria { 'in'('id', ids) fetchMode("someRelation", FetchMode.JOIN) // a few more joins setResultTransformer(CriteriaSpecification.

数据库函数返回特定半径内所有事件的id,按距离排序

之后,为了保持性能,我急切地将必要的集合加载到
中,使用条件如下:

    def events = Event.withCriteria {
        'in'('id', ids)
        fetchMode("someRelation", FetchMode.JOIN)
        // a few more joins
        setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
    }
然而,这打乱了订单。我注意到,这个条件查询的结果返回按id排序的所有事件。这在某种程度上是有意义的,因为
中的
不保证任何特殊排序(也不保证应该这样做)。然而,这带来了一点问题,因为我希望这个列表是有序的

所以我做的是:

    List<Event> temp = [];
    ids.each { id -> temp << events.find { it.id == id } }
    events = temp;
List temp=[];

ids.each{id->temp我认为至少有三种方法可以解决您的问题(我已经做了额外的研究和考虑):

SQL方式 根据,Postgres和mysql也可以按字段排序,但这有点棘手,因为它不直接受支持。正如你在要点讨论中所看到的,有不同的方法,但我认为更干净更简单的是最后一种方法:添加自定义order by子句

要在Grails中创建返回特定类型对象的自定义SQL查询,可以按照

Groovy方式(您当前的) 通过这种方式,您已经在O(n)中排序,消耗了一些额外的内存。 我不知道这个解决方案是否真的比你的好,但你应该试一试

另请参阅如何在groovy代码中查找性能问题

客户方式 将未排序的事件列表返回给具有排序数据的客户端,然后在客户端中对其进行排序。如果应用程序的客户端可以以更多方式对事件列表进行排序,我认为此解决方案可能会很有用(每个排序操作仅在客户端完成)

第四,第五。。。 由于这也是一个性能问题,因此还有其他可能的解决方案(取决于您的域/环境):

  • 急切地缓存一切,甚至有序的结果
  • 使用固定的点列表进行排序(如果我靠近p1,则使用p1进行排序)
  • 你的想法

我希望这会有所帮助。

您是否尝试过将
顺序(“id”、“asc”)
添加到您的标准中?@lifeisfoo将按id升序排列我的事件。但这不是我想要的。我有一个预定的顺序或按距离排列的事件id(我从数据库函数中接收到,距离不是一个属性,而是一个计算值)。我希望以某种方式保持这种顺序,或者在我的线程帖子的标准中/之后快速根据它进行排序。看看这个问题。你可以使用Grails HQL interface@lifeisfoo尝试这种技术。谢谢你的帮助,这就是我要找的,但是由于我使用postgres作为我的RDBMS,我没有按字段排序的特权>由于急于获取连接,我也在使用
distinct
,因此我似乎无法使用其他解决方案来进行字段排序。我想我必须想出其他办法。
ORDER BY (ID=10, ID=2, ID=56, ID=40) DESC
// only four id, for the sake of simplicity
def ids = [10, 2, 56, 40];

// get your events with your criteria
def events = Event.withCriteria {
    'in'('id', ids)
    fetchMode("someRelation", FetchMode.JOIN)
    // a few more joins
    setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY)
}

// create an array that maps event.id -> sortedEventIndex
def indexToIdArray = [];
// event with id 2 is at index 1
// event with id 10 is at index 0 
// ...
// [null, null, 1 , null, null, null, null, null, null, null, 0, ...]
ids.eachWithIndex{ num, idx -> indexToIdArray[$num] = $idx }

def sortedEvents = [];
events.each { ev -> sortedEvents[indexToIdArray[ev.id]] = ev }