Laravel 查询和过滤

问题描述 投票:0回答:2

我正在尝试找出过滤此查询的最佳方法,我尝试了一些不同的方法,但无法找到可靠的解决方案。

本质上,我们有一个通用查询,它可以完全满足其需要,问题是我需要能够过滤答案表上的用户输入。

$profiles = User::with('photos', 'answers')
        ->where('id', '!=', $user_id)
        ->where('gender', $gender)
        ->where('location', $location)
        ->where('deleted_at', null)
        ->whereNotExists(function($query) use ($user_id)
        {
            $query->select(DB::raw('user_id1, user_id2'))
                                    ->from('approves')
                                    ->whereRaw("users.id = approves.user_id2 AND approves.user_id1 = '$user_id'");
        })
        ->whereNotExists(function($query) use ($user_id)
        {
            $query->select(DB::raw('user_id1, user_id2'))
                    ->from('likes')
                    ->whereRaw("users.id = likes.user_id2 AND likes.user_id1 = '$user_id'");
        })
        ->take(15)
        ->get();

使用几个用户输入来更改查询,现在用户还可以根据用户的个人资料答案按各种其他条件进行过滤,这就是我陷入困境的地方。

answers表的布局是id,user_id,question_id,answer必须是这样的,以便以后可以扩展。

有谁知道如何使用各种其他输入来过滤此内容,例如,如果用户按 Question_id '1' 进行过滤并回答 'awesome'。值得注意的是,有多个输入,而不仅仅是一个可供比较,并且仅需要在已输入的情况下进行比较。

任何想法或建议都非常感激:)

编辑:

id | user_id | question_id | answer
1  | 2       | 1           | dad
2  | 2       | 2           | lion
3  | 2       | 3           | 5
php mysql laravel laravel-4
2个回答
2
投票

对于多个可能的问题/答案对,我将定义一个查询范围。现在这不是一个特别有效的查询,其他人可能有更好的答案,但这就是我要做的。

$profiles = User::with('photos', 'answers')
    ->where('id', '!=', $user_id)
    ->where('gender', $gender)
    ->where('location', $location)
    ->where('deleted_at', null)
    ->questionAnswer($questionAnswerArray)
    ->whereNotExists(function($query) use ($user_id)
    {
        $query->select(DB::raw('user_id1, user_id2'))
                                ->from('approves')
                                ->whereRaw("users.id = approves.user_id2 AND approves.user_id1 = '$user_id'");
    })
    ->whereNotExists(function($query) use ($user_id)
    {
        $query->select(DB::raw('user_id1, user_id2'))
                ->from('likes')
                ->whereRaw("users.id = likes.user_id2 AND likes.user_id1 = '$user_id'");
    })
    ->take(15)
    ->get();

然后在用户模型内部:

public function scopeQuestionAnswer($query, $qaArray)
{
    foreach($qaArray as $question => $answer)
    {
        $query->whereHas('answers', function($query) use ($question, $answer)
        {
            $query->whereQuestionId($question)
                  ->whereAnswer($answer);
        });
    }

    return $query;
}

这使用了带有 where array($question => $answer) 的参数数组,但应该很容易修改为您希望传递它们的方式。

我测试了这种用法,效果很好,但我再次无法评价它的效率。如果您需要按所有正确的问题/答案对进行过滤,则该解决方案并不适用,您可以在范围函数中使用“orWhereHas”来过滤其中的任何一个。


0
投票
<?php

namespace App\Http\Filters\V1;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

abstract class QueryFilter {
    protected $builder;
    protected $request;
    protected $sortable = [];

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function apply(Builder $builder) {
        $this->builder = $builder;

        foreach($this->request->all() as $key => $value) {
            if (method_exists($this, $key)) {
                $this->$key($value);
            }
        }

        return $builder;
    }

    protected function filter($arr) {
        foreach($arr as $key => $value) {
            if (method_exists($this, $key)) {
                $this->$key($value);
            }
        }

        return $this->builder;
    }

    protected function sort($value) {
        $sortAttributes = explode(',', $value);

        foreach($sortAttributes as $sortAttribute) {
            $direction = 'asc';

            if (strpos($sortAttribute, '-') === 0) {
                $direction = 'desc';
                $sortAttribute = substr($sortAttribute, 1);
            }

            if (!in_array($sortAttribute, $this->sortable) && !array_key_exists($sortAttribute, $this->sortable)) {
                continue;
            }

            $columnName = $this->sortable[$sortAttribute] ?? null;

            if ($columnName === null) {
                $columnName = $sortAttribute;
            }

            $this->builder->orderBy($columnName, $direction);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.