为什么 Rose::DB::Object sort_by RAND() 没有达到我的预期?

发布于 2024-07-29 16:52:13 字数 596 浏览 7 评论 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 BY 更正为 RAND() 吗?

I can't get it to work. I'm using this query:

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

When I turn on debugging in Rose::DB::Object::Manager, I see that the order clause is:

ORDER BY t1.id, RAND()

Where is that t1.id coming from? And any idea how I can correct the ORDER BY to be just RAND()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不交电费瞎发啥光 2024-08-05 16:52:13

来自 < code>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< /code> 在 @questions 中随机选择问题。

From the documentation for the sort_by parameter:

If selecting sub-objects (via require_objects or with_objects) that are related through "one to many" or "many to many" relationships, the first condition in the sort order clause must be a column in the primary table (t1). If this condition is not met, the list of primary key columns will be added to the beginning of the sort order clause automatically.

This is required in order to correctly associate sub-objects with their parent objects.

If you'd like to override this behavior, you can use the (as-yet undocumented) no_forced_sort boolean parameter.

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

But it is highly likely that this will cause sub-objects to be associated with the incorrect parent objects. What you'll need to make this work is a sort that is deterministically based on a unique characteristic of t1, but is otherwise random. That is, somefunc(t1.id) would be random but would always return the same result for a given value of t1.id, keeping all the children with the correct parents.

An obvious (and probably a lot more pragmatic) approach is to fetch all security questions for the user $username and then just randomly pick two:

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));
}

Now you've got your (maximum) NUM_RANDOM_QUESTIONS randomly selected questions in @questions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文