使用 Laravel Eloquent 进行高级查询

Posted

技术标签:

【中文标题】使用 Laravel Eloquent 进行高级查询【英文标题】:Advanced query with Laravel Eloquent 【发布时间】:2014-04-08 14:35:22 【问题描述】:

我已经尝试了一段时间来弄清楚如何使用 Laravel Eloquent 进行此查询。

查询:

DB::select('SELECT
    n.id,
    n.parent_id,
    n.name,
    n.file,
    n.created_at AS ts,
    f.mime,
    f.extension,
    IF(ch.id, 1, 0) AS dirs 
FROM nodes AS n 
LEFT JOIN nodes AS ch ON ch.parent_id=n.id
LEFT JOIN files AS f
    ON n.file = f.id
WHERE n.parent_id=?
GROUP BY n.id',array($path));

我有我的模型Node,它正在使用表nodes,我有一个方法nodefile() 用于我的Node 模型,包括return $this->belongsTo('NodeFile');,这是我需要加入的另一个模块。 NodeFile 模块正在使用表 files 并且这两个绑定在 nodes.filefiles.id 上。

这是我目前得到的:

Node::with(
    array('nodefile'=>function($query)
        $query->select('mime','extension');
    )
)->where('name','LIKE','%'.$q.'%')->get(array(
    'id', 'parent_id', 'name', 'file', 'created_at AS nts'
));

但我的查询中仍然需要IF(ch.id,1,0) AS dirs。并且还没有完成自我加入。

有人知道如何以最好的方式做到这一点吗?

【问题讨论】:

为什么不能将它保存在原始查询()中? ORM 的发明是为了简化事情,而不是让你把头撞到桌子上。什么可以被 ORMified - 好的,通过 Eloquent 实现。但是有些查询并不打算使用 ORMS 运行。所以,那就不要折磨他们了 你可以做一个$query->select(DB::raw(...)) 你没有提供足够的关于你的关系的信息,实际上对IF(ch.id, 1, 0) AS dirs感到困惑,所以不禁你可以检查this article,它是关于使用Eloquent关系技术的自我加入. @YourCommonSense,因为我想使用 Eloquent SoftDelete 您可以添加单独的“原始”选择列,这不会对软删除产生不利影响 【参考方案1】:

使用以下代码修复它。

Node::
  leftjoin('files','files.id','=','nodes.file')
->leftjoin('nodes AS ch','ch.parent_id','=','nodes.id')
->where('nodes.id','=',$path)
->groupBy('id')
->get(array(
    'nodes.id',
    'nodes.parent_id',
    'nodes.name',
    'nodes.file',
    'nodes.created_at AS nts',
    'files.mime',
    'files.extension',
    'ch.id AS dirs'
  ));

感谢@MarkBarker 提出将其制作成原始的想法,这帮助我找到了这个解决方案。

【讨论】:

以上是关于使用 Laravel Eloquent 进行高级查询的主要内容,如果未能解决你的问题,请参考以下文章

laravel 的 Eloquent ORM 查询前50条数据 怎么查

PHP笔记-laravel框架中Eloquent ORM实现增删改查

Laravel Eloquent - orWhereHas 方法 - 何时使用以及如何使用

如何在 Laravel 5.8 中使用 Eloquent 进行查询?

如何使用 Laravel Eloquent 和 Laravel Query Builder 进行联合查询?

Laravel 5 / Eloquent - 对属于多的关系进行查询过滤