我如何才能加入来自2个不同数据库的2个收藏集?

时间:2019-02-05 08:25:14

标签: php laravel

我在2个不同的数据库中有2个表-用户和帖子。 (它恰好位于不同的数据库中,无法更改)我想检索一个集合中的所有用户以及所有用户的帖子(计数)。这样最终结果将如下所示。

$model->username     // john
$model->fullname     // John Smith
$model->user_avatar  // jsm2m.jpg
$model->user_posts_count // 3  <-- from different database

我当然可以先检索所有用户,然后在另一个集合中将他的所有帖子计数都这样……

// I don't want 2 different collection like this....
$users = Users::all();
$user_posts_count = Posts::where('user_id', 1)->count();

但是为了方便起见,我希望全部都放在一个集合(变量)中。

用户表

id | username |   fullname   |  user_avatar
1      john      John Smith      jsm2m.jpg
2     martin     Bob Martin     jk3i302.jpg

帖子表(不同的数据库)

id | user_id |    post_body
1       1        hello world
2       1        howdy yall
3       1        what is up?

4 个答案:

答案 0 :(得分:2)

您可以通过执行以下操作来指定Post的连接:

class Post extends Model 
{
    protected $connection= 'other_db_connection';

    // 
}

很显然,此连接需要在您的config/database.php

中指定
'connections' => [
    // 
    //

    'other_db_connection' => [
        'driver'    => 'mysql',
        'host'      => 'localhost',
        'database'  => 'database2',
        'username'  => 'user2',
        'password'  => 'pass2'
        'charset'   => 'utf8',
        'collation' => 'utf8_unicode_ci',
        'prefix'    => '',
    ],
]

假设您的关系如下:

class Post extends Model 
{
    protected $connection= 'other_db_connection';

    public function user()
    {
        return $this->belongsTo(User::class); 
    }
}

class User extends Model 
{
    public function posts()
    {
        return $this->hasMany(Post::class); 
    }
}

然后您可以通过执行以下操作检索所需的内容:

$users = Users::withCount('posts')->all();

结果中将有一个名为posts_count的新列。

答案 1 :(得分:1)

对于一个简单的解决方案,您可以遍历每个用户,并在运行时将帖子数添加到新属性中。

$users = Users::all();
$users->each(function($user, $key){
  $user->posts_count = Posts::where('user_id', $user->id)->count();
});

编辑:

这是一种性能更高的解决方案。下面仅执行两个数据库查询,其中上面执行1 + N个查询,其中N是您在数据库中拥有的用户数。

$users = Users::all();
$postsCounts = Posts::select(\DB::raw('count(*) as posts_count'), 'user_id')
                     ->whereIn('user_id', $users->pluck('id')->all())
                     ->groupBy('user_id')
                     ->get();
$users->each(function($user, $key) use ($postsCounts) {
  $user->posts_count = $postsCounts->firstWhere('user_id', $user->id)->posts_count;
});

答案 2 :(得分:0)

假设这是Laravel,您可以参考https://laravel.com/docs/5.7/queries,该建议表明:

$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();

编辑:所以您可能想使用:

$users = DB::table('db1.users')
->leftJoin('db2.posts', 'db1.users.id', '=', 'db2.posts.user_id')
->get();

或者,如果您只想选择特定的列:

$users = DB::table('db1.users as users')
->leftjoin('db2.posts as posts', 'users.id', '=', 'posts.user_id')
->select(['users.column1', 'users.column2', 'posts.column1', 'posts.column2'])
->get();

或者,对于拥有多个用户的合并用户:

$users = DB::table('db1.users as users')
->select('users.*')
->join(DB::raw('(SELECT COUNT(user_id) AS numposts FROM db2.posts GROUP BY user_id) posts'),
function($join) {
    $join->on('users.id', '=', 'posts.user_id');
})
->get();

答案 3 :(得分:0)

对于来自不同数据库的联接表,您应该尝试

User::join('database2.posts','users.id','=','posts.user_id')
  ->select('fields you want to select')
  ->get();