OctoberCMS - 具有多对多关系的模型查询

Posted

技术标签:

【中文标题】OctoberCMS - 具有多对多关系的模型查询【英文标题】:OctoberCMS - Model query with relation manyToMany 【发布时间】:2017-08-12 08:14:35 【问题描述】:

我再次向社区寻求帮助... 场景:

我有两个表和一个数据透视表(类似于帖子和标签来提供一些上下文):

    table 1 (Evento):
        -id
        -....

    table 2 (Etiquetas):
        -id
        -etiqueta

    pivot table (Eventos_Etiquetas):
        -evento_id (pk)
        -etiqueta_id (pk)

关系设置为:

public $belongsToMany = [
    'eventos' => ['JML\Gkb\Models\Evento', 'table' => 'jml_gkb_eventos_etiquetas']
];

public $belongsToMany = [
    'etiquetas' => ['JML\Gkb\Models\Etiqueta', 'table' => 'jml_gkb_eventos_etiquetas']
];

现在,我想要实现的目标:

- 获取具有任何单个标签的所有事件,而不考虑输入(或)的顺序。

-获取所有具有所有标签的事件,而不考虑输入(和)的顺序。

您可以想象我正在为此苦苦挣扎,因为我是十月/Laravel 查询构建器的新手(而不是 sql)。

到目前为止我做了什么:

if (Session::get('tipo') == 'etiqueta')
    $pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
    if (Session::get('modo') == 0)
        $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa)
            foreach ($pesquisa as $palavra)
                $query->where('etiqueta', 'like', "%$palavra%");
            
        )->orderBy('id', 'DESC')->paginate(25);
    
    if (Session::get('modo') == 1)
        $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa)
            foreach ($pesquisa as $palavra)
                $query->orWhere('etiqueta', 'like', "%$palavra%");
            
        )->orderBy('id', 'DESC')->paginate(25);
    

用户输入由 $temp 变量传递,并被拆分为单词到 $pesquisa 数组变量。 'modo' 定义用户是否假装通过 AND (0) 或 OR (1) 进行搜索。基于该选择构建一个查询以尝试使用 $palavra 变量作为 $pesquisa 的任何单词来获取结果。

这个结果:

在 modo == 0 中,我只能获取用户输入的一个标签的事件,如果它有多个单词(第一个单词上不存在的任何字母),则不会得到任何结果。

在 modo == 1 中,它获取所有事件。

在这两种情况下,我都没有收到任何没有任何标签(礼仪)的事件——正确的行为。

我尝试了其他一些方法,但无济于事...在我看来,这是最合乎逻辑的尝试...有人可以指出正确的方向吗?

TIA

JL

【问题讨论】:

如果您收到“正确的行为”,那么问题是什么? 唯一能按预期工作的是所有没有任何“Etiqueta”的“Eventos”都被过滤掉了。剩下的(也是主要目标)情况没有得到预期的结果。泰 【参考方案1】:

经过一些尝试,我解决了一半的问题。我想在用户输入上获得任何“Etiqueta”而不是关于它们的顺序的任何“Evento”的部分终于可以正常工作了。

继续往下看

    if (Session::get('tipo') == 'etiqueta')
    $pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
    $cadeiapesquisa = implode('|', $pesquisa);
 /***** NOT WORKING YET *****/
    if (Session::get('modo') == 0)
        $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($pesquisa)
            foreach ($pesquisa as $palavra)
                $query->where('etiqueta', 'like', "%$palavra%");
            
        )->orderBy('id', 'DESC')->paginate(25);
    
/****** THIS IS WORKING FINE ! *******/
    if (Session::get('modo') == 1)
        if ( count ($pesquisa) > 0 && !($temp == null))
            $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa)

                $query->where('etiqueta', 'regexp', "$cadeiapesquisa");

            )->orderBy('id', 'DESC')->paginate(25);
         else 
            Evento::paginate(25);
        
    

第一方正在战斗,但我会到达那里。 :)

TIA

JL

[编辑]

问题已解决...到目前为止,我所做的测试所产生的代码片段如下:

    if (Session::get('tipo') == 'etiqueta')
    $pesquisa = preg_split('/\s+/', $temp, -1, PREG_SPLIT_NO_EMPTY);
    $cadeiapesquisa = implode('|', $pesquisa);
    $contagem = count($pesquisa);
    if (Session::get('modo') == 0)
        if ( strlen($cadeiapesquisa) > 0 )
            $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa, $contagem)

                $query->where('etiqueta', 'regexp', "$cadeiapesquisa")->groupBy('evento_id')->having(DB::raw("COUNT('etiqueta_id')"), '>=', $contagem );

            )->paginate(25);
         else 
            $this['records'] = Evento::paginate(25);
        
    
    if (Session::get('modo') == 1)
        if ( strlen($cadeiapesquisa) > 0 )
            $this['records'] = Evento::with('etiquetas')->whereHas('etiquetas', function($query) use ($cadeiapesquisa)

                $query->where('etiqueta', 'regexp', "$cadeiapesquisa");

            )->paginate(25);
         else 
            $this['records'] = Evento::paginate(25);
        
    

JL

【讨论】:

我在最后一个语句中有错字。 Evento::paginate(25) 在哪里;必须是 $this['records'] = Evento::paginate(25);

以上是关于OctoberCMS - 具有多对多关系的模型查询的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 中查询用户的多对多关系

CoreData:查询一对多对多的关系

将SQL查询转换为具有多对多关系的Rails查询,最佳实践是什么?

Django ORM - 通过模型查询多对多?

Django:通过参数序列化具有多对多关系的模型

多对多关系的查询集按列表中的匹配数排序