如何在 Eloquent 中查询特定关系
Posted
技术标签:
【中文标题】如何在 Eloquent 中查询特定关系【英文标题】:How to query specific relation(s) in Eloquent 【发布时间】:2020-11-24 10:49:59 【问题描述】:我有这样结构的数据库表(有点像国际会议论文集):
languages (id, abbr)
papers (id, title, fulltext, language_id)
keywords (id)
keyword_translations (id, label, keyword_id, language_id) // cointains language-specific tranlation of given keyword
paper_keywords (id, paper_id, keyword_id) //M:N relation between papers and keywords
usage (id)
usage_translations (id, label, usage_id, language_id)
paper_usage (id, paper_id, usage_id) //M:N relation between papers and usages
这描述了论文及其元数据。所需的 UI 应该是多种语言的,因此有“翻译表”。
在我的 Eloquent 模型中,我已经建立了所有简单的 M:N belonsToMany
关系,例如“所有使用此设备的论文”。模型如下所示:
class Paper extends Model
public function keywords()
return $this->belongsToMany('App\Keyword', 'paper_keyword');
public function usages()
return $this->belongsToMany('App\Usage', 'paper_usage');
class Keyword extends Model
public function translations()
return $this->hasMany('App\KeywordTranslation');
public function papers()
return $this->belongsToMany('App\Paper', 'paper_keyword');
……用法相同。
现在我需要查询由其 ID 给出的特定论文(或者可能是多篇论文)以及属于它的所有关键字和用法 - 但仅具有给定 language_id 的那些。 (这个language_id只涉及翻译(对于UI),论文可以有不同的language_id。一个典型的例子是我想看一篇斯洛伐克语或波兰语的论文,但是UI是捷克语,所以应该有捷克语关键字和其他元数据的标签)。
我知道我可以做到App\Paper::with(['usages.translations', 'keywords.translations'])->find(1605);
,但这会带来所有翻译,而不仅仅是特定于语言的翻译。在纯 SQL 中,我会简单地使用一些别名连接所有表并查询 WHERE keyword_translations.language_id = 1
,但在 Eloquent 中?
我想避免需要修改数据库的解决方案。
【问题讨论】:
您是否正在寻找带有orWhere()
子句的where()
?
【参考方案1】:
我认为您需要以下查询
$languageId = 'language_id';
$papers = App\Paper::with(['usages.translations', 'keywords.translations'])
->whereHas('usages.translations', function($query) use ($languageId)
$query->where('language_id', $languageId);
)
->whereHas('keywords.translations', function($query) use ($languageId)
$query->where('language_id', $languageId);
)
->get();
【讨论】:
不幸的是,这不起作用 - 它会获取所有语言突变。【参考方案2】:听起来你需要的是一个嵌套查询,如下所示:
App\Paper::with(['usages.translations', 'keywords.translations'])
->where('usages.translations.language_id', 'your_id_goes_here')
->orWhere('keywords.translations.language_id', 'your_id_goes_here')
->get();
【讨论】:
谢谢,我试过了,但是我收到了Illuminate/Database/QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'usages.translation s.language_id' in 'where clause' (SQL: select * from `papers` where `usages`.`translations`.`language_id` = 1 or `keywords` .`translations`.`language_id` = 1)'
以上是关于如何在 Eloquent 中查询特定关系的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel Eloquent 中构建具有多级关系的查询
如何在 Laravel 中使用多表查询而不使用 Eloquent 关系