【问题标题】:Use more complex where clauses in Scout在 Scout 中使用更复杂的 where 子句
【发布时间】:2019-01-28 10:09:12
【问题描述】:

我是 Laravel Scout 的快乐用户。

现在我想扩展我的搜索:

        $data
            = new UserOverviewResourceCollection(User::search($searchphrase)
            ->currentStatus('active')->orderBy('lastname', 'asc')
            ->orderBy('firstname', 'asc')
            ->paginate(config('pagination.length')));

currentStatus 来自https://github.com/spatie/laravel-model-status

现在我收到回复,不支持 currentStatus。我认为在从侦察员返回后过滤 User::search 的结果可能是个好主意?

另一个想法:我想添加更复杂的 where 子句:

->where([
                [
                    'starts_on',
                    '<',
                    Carbon::now()->toDateTimeString(),
                ],
                [
                    'ends_on',
                    '>',
                    Carbon::now()->toDateTimeString(),
                ],
            ])

也许你有更好的主意?

【问题讨论】:

    标签: laravel laravel-5 laravel-5.7 laravel-scout


    【解决方案1】:

    重写它应该可以工作。

     $data
                = new UserOverviewResourceCollection(User::search($searchphrase)
                ->where('starts_on','<',now())
                ->orderBy('lastname', 'asc')
                ->orderBy('firstname', 'asc')
                ->paginate(config('pagination.length')));
    

    请注意,now() 只是一个返回当前时刻 Carbon 实例的全局辅助函数。只是写的更短,没有其他使用它的理由。

    如果你想要grouped where 查询,你可以这样做:

     $data
                = new UserOverviewResourceCollection(User::search($searchphrase)
                ->where(function($q) {
                   $q->where('starts_on','<',now())->where('ends_on','>',now())
                })
                ->orderBy('lastname', 'asc')
                ->orderBy('firstname', 'asc')
                ->paginate(config('pagination.length')));
    

    然后您应该能够将其导出到UserOverviewResourceCollection 作为local scope,例如:

    public function scopeActive($q) {
        return $q->where('starts_on','<',now())->where('ends_on','>',now())
    }
    

    然后你可以使用这样的东西:

     $data
                = new UserOverviewResourceCollection(User::search($searchphrase)
                ->active()
                ->orderBy('lastname', 'asc')
                ->orderBy('firstname', 'asc')
    
    

    这是我脑子里写的,所以可能有错别字。

    【讨论】:

    • 嗯,范围不起作用,实际上 (Method Laravel\\Scout\\Builder::active does not exist)。不幸的是,分组 where 也不起作用 (laravel.com/docs/5.7/scout#where-clauses) -> Too few arguments to function Laravel\\Scout\\Builder::where(), 1 passed in .. line 91 and exactly 2 expected
    • 让我们一步一步来。第一段代码有效吗?如果没有,您能否删除 -&gt;where('starts_on','&lt;',now()) 部分并验证它是否可以正常工作?
    • 好吧...不,第一个块不起作用:“消息”:“数字条件的无效语法:starts_on=where 子句,它会起作用。
    • laravel.com/docs/5.7/scout#where-clauses 似乎复杂的(无论这意味着什么)查询是不允许的,所以这可能是它不起作用的原因。从长远来看,您可以尝试将where 查询放在search() 之前,否则您可能必须在Algolia 中索引starts_onends_on 字段,然后通过他们的API 在那里进行查询。另一种丑陋的解决方法可能是从 Algolia 获取 ID,然后使用 whereIn('id',$arrayOfIDsFromAlgolia) 在您的数据库上重新执行查询,但在 Algolia 中应该有办法做到这一点。
    【解决方案2】:
     $data
            = new UserOverviewResourceCollection(User::search($searchphrase)
            ->currentStatus('active')->orderBy('lastname', 'asc')
            ->where(function($q){
                $query->where('starts_on', '<',Carbon::now()->toDateTimeString());
                $query->where('ends_on', '>',Carbon::now()->toDateTimeString());
             })
            ->orderBy('firstname', 'asc')
            ->paginate(config('pagination.length')));
    

    试试这个代码。这将满足您复杂的 where 条件

    【讨论】:

    • 您好,谢谢。不幸的是它仍然返回Method Laravel\\Scout\\Builder::currentStatus does not exist.
    • 嗨,currentStatus 函数是写在你的问题本身中的。请删除“->currentStatus('active')”并尝试。
    • 是的,它写在那里是有充分理由的 - 我需要它 ;-) currentStatus 来自 currentStatus 来自 github.com/spatie/laravel-model-status 正如我在最初的问题中所写的那样:-)
    【解决方案3】:

    我也确实需要类似的功能,但恐怕目前不可能(Laravel 8)

    根据文档; Laravel\Scout\Builder(这是 search() 返回的)只有 where 方法的一个真正基本的实现,只能处理 2 个参数。 这是 scout 包中的代码:

    /**
     * Add a constraint to the search query.
     *
     * @param  string  $field
     * @param  mixed  $value
     * @return $this
     */
    public function where($field, $value)
    {
        $this->wheres[$field] = $value;
    
        return $this;
    }
    

    https://laravel.com/docs/8.x/scout#where-clauses

    search() 放在所有常规的 eloquent 构建器方法后面也不起作用,因为 search 将只是模型的静态函数。

    希望以后会有所改进。

    【讨论】:

      【解决方案4】:

      您可以扩展 Builder 并添加 currentStatus 方法以在 builder 中存储所需的状态。查看示例 https://github.com/matchish/laravel-scout-elasticsearch/issues/47#issuecomment-526287359

      然后您需要实现自己的引擎并在那里使用构建器构建查询。 这是 ElasticSearch 引擎的示例 https://github.com/matchish/laravel-scout-elasticsearch/blob/06c90914668942b23ffaff7d58af5b9db1901fb1/src/Engines/ElasticSearchEngine.php#L135

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-31
        • 2010-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-27
        • 1970-01-01
        相关资源
        最近更新 更多