php Laravel雄辩:OrderBy特殊条件

roejwanj  于 12个月前  发布在  PHP
关注(0)|答案(3)|浏览(120)

我正在创建一个小的新闻系统,这些是我可用的表:

新闻表

| ID|标题|文本|
| --|--|--|
| 1 |新闻1|- -一种|
| 2 |新闻2|- -一种|
| 3 |新闻3|- -一种|
| 4 |新闻4|- -一种|
| 5 |新闻5|- -一种|

类别表

| ID|名称|
| --|--|
| 1 |膜|
| 2 |动漫|
| 3 |书|
| 4 |系列|
| 5 |电视剧|
| 6 |警察|
| 7 |犯罪|

主题表

| ID|名称|
| --|--|
| 1 |膜|
| 2 |动漫|
| 3 |书|
| 4 |漫威|
| 5 |电视剧|
| 6 |警察|
| 7 |犯罪|

相关员额/职类表

| ID|邮政ID|类别id|
| --|--|--|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
| 4 | 2 | 2 |
| 5 | 3 | 5 |
| 6 | 3 | 4 |
| 7 | 4 | 5 |
| 8 | 4 | 6 |
| 9 | 5 | 5 |
| 10 | 5 | 7 |

相关文章/主题表

| ID|邮政ID|主题ID|
| --|--|--|
| 1 | 1 | 1 |
| 2 | 2 | 3 |
| 3 | 3 | 5 |
| 4 | 4 | 5 |
| 5 | 5 | 7 |
写文章时,必须指定类别和主题。主题和类别是相同的,但有区别:您可以分配无限的类别,但只有1个主题。
当我按类别搜索文章时,我会得到包含该类别的文章列表。我想把第一个职位,有相应的主题搜索,然后所有其他人。
如果我运行以下查询

$search = 'TV series';

$query = News::with([
    'category_related',
    'topic_related'
])
->whereHas('category_related', function($query) use ($search){

    $query->where('name', 'like', '%'.$search.'%');
        
})
->paginate(20);

我得到这个列表:
1.新闻5
1.新闻4
1.新闻3
我想要这个列表:
1.新闻4
1.新闻3
1.新闻5
在我想获得的第二个列表中,第5条新闻排在最后,因为主题与搜索“电视剧”不同。
有人能帮帮我吗?
Thanks in advance

编辑

  • 按类别筛选新闻项目
  • 我检查搜索的类别是否也对应于一个主题
  • 如果主题检查是成功的,我把这些新闻项目,并把它们放在第一位
  • 列出所有其他新闻项目
xcitsw88

xcitsw881#

如果你想创建一个自定义搜索顺序,你需要使用FIELD()。据我所知,没有合适的对应物,所以你需要像下面这样使用orderByRaw()

orderByRaw('FIELD(topic_id, 5) DESC, created_at ASC')

如果你想先得到topic_id 5的结果,然后再得到所有其他的结果,按created_at排序。

i7uaboj4

i7uaboj42#

如果我理解正确的话,应该是这样的:

$search = 'TV series';

$query = Posts::with([
    'category_related',
    'topic_related'
])
->whereHas('category_related', function($query) use ($search){

    $query->where('name', 'like', '%'.$search.'%');
        
})
->orderBy('news.id', 'desc')
->orderBy('topic.id')
->paginate(20);

诀窍是,首先按最新消息排序,然后按主题排序。相反的方式是行不通的。

    • 我现在知道搜索必须在topic_related表中完成。然后结果必须是UNION ALL与搜索不匹配的新闻。

就是这么说的但我相信这仍然不是他真正想要的。请用简短清晰的句子再说一遍,不要混淆类别和主题。你想去哪里找?你想用什么样的订货单?类别和主题不是一样的吗(至少在你使用它的时候)?
抱歉,无意冒犯。我可能是这里的问题。
祝你好运!

nom7f22z

nom7f22z3#

我找到了解决办法,在这里我试图解释我是如何做到的。
首先,我运行一个查询来获取某个类别中的新闻项列表。类别的选择由用户做出。
在下面的例子中,我手动输入类别,只是为了展示它是如何工作的:

$search = 'TV series';

$query = News::with([
    'category_related',
    'topic_related'
])
->whereHas('category_related', function($query) use ($search){

    $query->where('name', $search);
        
})
->orderBy(' created_at', 'desc')
->paginate(20);

于是,我创造了一个资源:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class NewsListResource extends JsonResource{

    public function toArray($request){
        
        return [
            'id' => $this->id,
            'title' => $this->title,
            'topic_id' => !empty($this->topic_related) ? $this->topic_related->id : null,
        ];

    }
    
}

在创建的资源中,我检查与“topics”的关系是否有结果,如果有,我打印与“topic”相关的id。
现在我用sortByDesc方法来使用资源:

$data = NewsListResource::collection($query)->sortByDesc('topic_id')->values();

我只是获取新闻条目列表,根据主题ID对其进行重新排序(这样包含主题的新闻条目就被放在第一位)。
我希望我的解释已经很清楚了

  • 其他解决方案 *
// Count topic related
$query->withCount(['topic_related as count_topic' => function($query) use($search){
    $query->where('name', $search);
}]);

// Order
$query->orderByDesc('count_topic')->orderBy('created_at', 'desc');

相关问题