在Scout中使用更复杂的where子句

时间:2019-01-28 10:09:13

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

我是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(),
                ],
            ])

也许您有个更好的主意?

4 个答案:

答案 0 :(得分:0)

好好重写它,因为它应该起作用。

 $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')));

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

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')

我从脑子里写了这个,所以可能会有错别字。

答案 1 :(得分:0)

 $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')));

尝试此代码。这将满足您复杂的条件

答案 2 :(得分:0)

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

根据文档; Laravel\Scout\Builder(这是search()返回的内容)仅具有where方法的非常基本的实现,并且只能处理2个参数。 这是侦查包中的代码:

/**
 * 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()放在所有常规的雄辩的构建器方法后面将不会起作用,因为search只会是模型的静态函数。

希望以后会有所改善。

答案 3 :(得分:0)

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

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