0

我无法让它工作。我正在使用这个查询:

my $user_questions 
    = RoseDB::UserSecurityQuestion::Manager->get_user_security_questions(
        query        => [
                          'user.username' => $username,
                        ],
        with_objects => ['User','SecurityQuestion'],
        sort_by      => 'RAND()',
        limit        => 2,
    );

当我在 Rose::DB::Object::Manager 中打开调试时,我看到 order 子句是:

ORDER BY t1.id, RAND()

那是t1.id从哪里来的?知道如何纠正ORDER BYRAND()吗?

4

1 回答 1

3

参数的文档中sort_by

如果选择通过“一对多”或“多对多”关系关联的子对象(通过 require_objects 或 with_objects),排序顺序子句中的第一个条件必须是主表 (t1) 中的列。如果不满足此条件,则主键列列表将自动添加到排序顺序子句的开头。

为了将子对象与其父对象正确关联,这是必需的。

如果您想覆盖此行为,可以使用(尚未记录的)no_forced_sort布尔参数。

my $user_questions =
  RoseDB::UserSecurityQuestion::Manager->get_user_security_questions(
    ...
    sort_by        => 'RAND()',
    no_forced_sort => 1);

但这很可能会导致子对象与不正确的父对象相关联。完成这项工作需要的是一种确定性地基于 t1 的独特特征的排序,但在其他方面是随机的。也就是说,这somefunc(t1.id)将是随机的,但对于给定的 t1.id 值,总是会返回相同的结果,从而使所有孩子都拥有正确的父母。

一个明显(可能更实用)的方法是为用户获取所有安全问题,$username然后随机选择两个:

my $user_questions =
  RoseDB::UserSecurityQuestion::Manager->get_user_security_questions(
    query        => [ 'user.username' => $username ],
    with_objects => ['User','SecurityQuestion']);

use constant NUM_RANDOM_QUESTIONS => 2;

my @questions;

for(1 .. NUM_RANDOM_QUESTIONS)
{
  last unless(@$user_questions);
  push(@questions, splice(@$user_questions, int(rand(@$user_questions)), 1));
}

现在,您的(最多)NUM_RANDOM_QUESTIONS随机选择的问题在@questions.

于 2009-07-29T12:28:18.760 回答