1

我正在使用 MongoDB 库https://github.com/jenssegers/laravel-mongodb version 3.1.0-alpha我在 MongoDB中Laravel 5.3.28有两个集合,我想在它们之间建立一个 hasMany 关系。意味着每个员工执行许多任务。我在任务集合中使用了参考并添加了employee_ids。

以下是我的代码:

MongoDB:

第一个集合:员工

{
    "_id" : ObjectId("586ca8c71a72cb07a681566d"),
    "employee_name" : "John",
    "employee_description" : "test description",
    "employee_email" : "john@email.com",
    "updated_at" : "2017-01-04 11:45:20",
    "created_at" : "2017-01-04 11:45:20"
},
{
    "_id" : ObjectId("586ca8d31a72cb07a6815671"),
    "employee_name" : "Carlos",
    "employee_description" : "test description",
    "employee_email" : "carlos@email.com",
    "updated_at" : "2017-01-04 11:45:20",
    "created_at" : "2017-01-04 11:45:20"
}

第二集:任务

{
    "_id" : ObjectId("586ccbcf1a72cb07a6815b04"),
    "task_name" : "New Task",
    "task_description" : "test description",
    "task_status" : 1,
    "task_start" : "2017-04-01 12:00:00",
    "task_end" : "2017-04-01 02:00:00",
    "task_created_at" : "2017-04-01 02:17:00",
    "task_updated_at" : "2017-04-01 02:17:00",
    "employee_id" : [ 
        ObjectId("586ca8c71a72cb07a681566d"), 
        ObjectId("586ca8d31a72cb07a6815671")
    ]
},
{
    "_id" : ObjectId("586cd3261a72cb07a6815c69"),
    "task_name" : "2nd Task",
    "task_description" : "test description",
    "task_status" : 1,
    "task_start" : "2017-04-01 12:00:00",
    "task_end" : "2017-04-01 02:00:00",
    "task_created_at" : "2017-04-01 02:17:00",
    "task_updated_at" : "2017-04-01 02:17:00",
    "employee_id" : ObjectId("586ca8c71a72cb07a681566d")
}

Laravel: 型号: 员工:

<?php
namespace App\Models;

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Employee extends Eloquent {

    protected $collection = 'employee';
    protected $primaryKey = '_id';

    public function tasks()
    {
        return $this->hasMany('App\Models\Task');
    }
}

Laravel:模型:任务:

<?php
namespace App\Models;

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Task extends Eloquent {

    protected $collection = 'task';
    protected $primaryKey = '_id';

    public function employees()
    {
        return $this->belongsTo('App\Models\Employee');
    }
} 

我想获得分配给特定员工的任务。

控制器:

public function EmployeeData($data)
{
    $employees = Employee::with('tasks')->where('_id', new \MongoDB\BSON\ObjectID('586ca8d31a72cb07a6815671'))->get();
        echo "<pre>";
        print_r($employees);exit;
}

输出:

Illuminate\Database\Eloquent\Collection Object
(
    [items:protected] => Array
        (
            [0] => App\Models\Employee Object
                (
                    [connection:protected] => mongodb
                    [collection:protected] => lt_employees
                    [primaryKey:protected] => _id
                    [employee_id:App\Models\Employee:private] => 
                    [employee_name:App\Models\Employee:private] => 
                    [employee_description:App\Models\Employee:private] => 
                    [employee_email:App\Models\Employee:private] => 
                    [employee_created_at:App\Models\Employee:private] => 
                    [employee_updated_at:App\Models\Employee:private] => 
                    [parentRelation:protected] => 
                    [table:protected] => 
                    [keyType:protected] => int
                    [perPage:protected] => 15
                    [incrementing] => 1
                    [timestamps] => 1
                    [attributes:protected] => Array
                        (
                            [_id] => MongoDB\BSON\ObjectID Object
                                (
                                    [oid] => 586ca8d31a72cb07a6815671
                                )

                            [employee_name] => Carlos
                            [employee_description] => test description
                            [employee_email] => carlos@email.com
                            [updated_at] => 2017-01-04 11:45:20
                            [created_at] => 2017-01-04 11:45:20
                        )

                    [original:protected] => Array
                        (
                            [_id] => MongoDB\BSON\ObjectID Object
                                (
                                    [oid] => 586ca8d31a72cb07a6815671
                                )

                            [employee_name] => Carlos
                            [employee_description] => test description
                            [employee_email] => carlos@email.com
                            [updated_at] => 2017-01-04 11:45:20
                            [created_at] => 2017-01-04 11:45:20
                        )

                    [relations:protected] => Array
                        (
                            [tasks] => Illuminate\Database\Eloquent\Collection Object
                                (
                                    [items:protected] => Array
                                        (
                                        )

                                )

                        )

                    [hidden:protected] => Array
                        (
                        )

                    [visible:protected] => Array
                        (
                        )

                    [appends:protected] => Array
                        (
                        )

                    [fillable:protected] => Array
                        (
                        )

                    [guarded:protected] => Array
                        (
                            [0] => *
                        )

                    [dates:protected] => Array
                        (
                        )

                    [dateFormat:protected] => 
                    [casts:protected] => Array
                        (
                        )

                    [touches:protected] => Array
                        (
                        )

                    [observables:protected] => Array
                        (
                        )

                    [with:protected] => Array
                        (
                        )

                    [exists] => 1
                    [wasRecentlyCreated] => 
                )

        )

)

在输出中,关系任务项为空。

谁能建议我黑白收藏的关系是正确的?

更新

我使用了 belongsToManyin 关系。现在我的模型是:

在员工模型中:

    public function tasks()
    {
        return $this->belongsToMany('App\Models\Task');
    }

在任务模型中:

    public function employees()
    {
        return $this->belongsToMany('App\Models\Employee');
    }

这些是文件:

员工收藏

{
    "_id" : ObjectId("586ca8c71a72cb07a681566d"),
    "employee_name" : "Carlos",
    "employee_description" : "test description",
    "employee_email" : "carlos@email.com",
    "updated_at" : "2017-01-04 11:45:20",
    "created_at" : "2017-01-04 11:45:20",
    "task_ids" : [ 
        ObjectId("586ccbcf1a72cb07a6815b04"), 
        ObjectId("586cd3261a72cb07a6815c69")
    ]
}, 
{
    "_id" : ObjectId("586ca8d31a72cb07a6815671"),
    "employee_name" : "John",
    "employee_description" : "test description",
    "employee_email" : "john@email.com",
    "updated_at" : "2017-01-04 11:45:20",
    "created_at" : "2017-01-04 11:45:20"
}

任务集合

{
    "_id" : ObjectId("586ccbcf1a72cb07a6815b04"),
    "task_name" : "New Task",
    "task_description" : "test description",
    "task_status" : 1,
    "task_start" : "2017-04-01 12:00:00",
    "task_end" : "2017-04-01 02:00:00",
    "task_created_at" : "2017-04-01 02:17:00",
    "task_updated_at" : "2017-04-01 02:17:00",
    "employee_ids" : [ 
        ObjectId("586ca8c71a72cb07a681566d"), 
        ObjectId("586ca8d31a72cb07a6815671")
    ]
},
{
    "_id" : ObjectId("586cd3261a72cb07a6815c69"),
    "task_name" : "2nd Task",
    "task_description" : "test description",
    "task_status" : 1,
    "task_start" : "2017-04-01 12:00:00",
    "task_end" : "2017-04-01 02:00:00",
    "task_created_at" : "2017-04-01 02:17:00",
    "task_updated_at" : "2017-04-01 02:17:00",
    "employee_ids" : ObjectId("586ca8c71a72cb07a681566d")
}

我得到了第一个拥有这些文件的员工:

$employee = Employee::with('tasks')->first();
dd($employee);

我得到了空关系的输出:

Employee {#176
  #connection: "mongodb"
  #collection: "employee"
  #primaryKey: "_id"
  -employee_id: null
  -employee_name: null
  -employee_description: null
  -employee_email: null
  -employee_created_at: null
  -employee_updated_at: null
  #parentRelation: null
  #table: null
  #keyType: "int"
  #perPage: 15
  +incrementing: true
  +timestamps: true
  #attributes: array:10 [
    "_id" => ObjectID {#170}
    "employee_name" => "Carlos"
    "employee_description" => "test description"
    "employee_email" => "carlos@email.com"
    "updated_at" => "2017-01-04 11:45:20"
    "created_at" => "2017-01-04 11:45:20"
    "task_ids" => array:2 [
      0 => ObjectID {#174}
      1 => ObjectID {#175}
    ]
  ]
  #original: array:10 [
    "_id" => ObjectID {#170}
    "employee_name" => "Carlos"
    "employee_description" => "test description"
    "employee_email" => "carlos@email.com"
    "updated_at" => "2017-01-04 11:45:20"
    "created_at" => "2017-01-04 11:45:20"
    "task_ids" => array:2 [
      0 => ObjectID {#174}
      1 => ObjectID {#175}
    ]
  ]
  #relations: array:1 [
    "tasks" => Collection {#173
      #items: []
    }
  ]
  #hidden: []
  #visible: []
  #appends: []
  #fillable: []
  #guarded: array:1 [
    0 => "*"
  ]
  #dates: []
  #dateFormat: null
  #casts: []
  #touches: []
  #observables: []
  #with: []
  +exists: true
  +wasRecentlyCreated: false
}
4

1 回答 1

3

我从您的另一个问题中了解到,一项任务可以属于许多员工,对吗?所以你应该在你的模型中使用belongsToMany关系。Task此外,您的示例“任务”集合显示,在一个文档employee_id中是一个数组,而在另一个文档中它是一个 ObjectId,而两者都应该是数组。

无论如何,我很难弄清楚这一点,但我已经看到你不能hasMany用作 的倒数belongsToMany,因为belongsToMany创建了一个 id 数组,并且hasMany不适用于数组。我会说我们需要类似的东西hasManyInArray,但是当我关联belongsToMany关系时,“父”文档会创建一个 id 数组,这让我认为belongsToMany即使它不“属于”父也应该使用但实际上“有”。因此,当您将员工与这样的任务相关联时:

$task->employees()->save($employee);

“employee”文档最终将具有一个“task_ids”属性,该属性具有它应该具有的唯一任务 ID。所以这似乎是 Jenssegers 的方法:belongsToMany在两种模型中使用:

Laravel: 型号: 员工:

<?php
namespace App\Models;

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Employee extends Eloquent
{
    protected $collection = 'employee';

    public function tasks()
    {
        return $this->belongsToMany(Task::class);
    }
}

Laravel:模型:任务:

<?php
namespace App\Models;

use Jenssegers\Mongodb\Eloquent\Model as Eloquent;

class Task extends Eloquent
{
    protected $collection = 'task';

    public function employees()
    {
        return $this->belongsToMany(Employee::class);
    }
}

你会这样使用:

// Give a task a new employee
$task->employees()->save($employee);

// Or give an employee a new task
$employee->tasks()->save($task);

唯一的一点是,当您查看数据库时,您会看到您的员工文档有一个名为“task_ids”的数组,其中包含每个员工唯一拥有的任务的 ID。我希望这会有所帮助。


只是一些旁注,您知道您不必在每个模型上定义主键的名称,对吗?你不需要这个:

protected $primaryKey = '_id';

此外,您不必定义集合的名称(即protected $collection = 'employee';),除非您真的希望它们是单数(默认情况下它们是复数)。


我半夜起床(这里是凌晨 3 点 52 分)并在电脑上检查了一些东西,然后检查了所以看到了你的问题,我希望这次我能尽快回答你,我们似乎在不同的时区。

更新

这些是我为测试创建的文档:

员工集合

{
    "_id" : ObjectId("5870ba1973b55b03d913ba54"),
    "name" : "Jon",
    "updated_at" : ISODate("2017-01-07T09:51:21.316Z"),
    "created_at" : ISODate("2017-01-07T09:51:21.316Z"),
    "task_ids" : [ 
        "5870ba1973b55b03d913ba56"
    ]
},
{
    "_id" : ObjectId("5870ba1973b55b03d913ba55"),
    "name" : "Doe",
    "updated_at" : ISODate("2017-01-07T09:51:21.317Z"),
    "created_at" : ISODate("2017-01-07T09:51:21.317Z"),
    "task_ids" : [ 
        "5870ba1973b55b03d913ba56"
    ]
}

任务集合

{
    "_id" : ObjectId("5870ba1973b55b03d913ba56"),
    "name" : "New Task",
    "updated_at" : ISODate("2017-01-07T09:51:21.317Z"),
    "created_at" : ISODate("2017-01-07T09:51:21.317Z"),
    "employee_ids" : [ 
        "5870ba1973b55b03d913ba54", 
        "5870ba1973b55b03d913ba55"
    ]
}

有了这些文件,我得到了第一个这样的员工:

$employee = Employee::with('tasks')->first();
dd($employee);

在输出中我们可以看到关系属性是一个数组:

Employee {#186 ▼
  #collection: "employee"
  #primaryKey: "_id"
  // Etc.....
  #relations: array:1 [▼
    "tasks" => Collection {#199 ▼
      #items: array:1 [▼
        0 => Task {#198 ▼
          #collection: "task"
          #primaryKey: "_id"
          // Etc....
          #attributes: array:5 [▼
            "_id" => ObjectID {#193}
            "name" => "New Task"
            "updated_at" => UTCDateTime {#195}
            "created_at" => UTCDateTime {#197}
            "employee_ids" => array:2 [▶]
          ]
        }
      ]
    }
  ]
}

更新 2

belongsToMany方法不在您提到的文件中,因为该类(即Jenssegers\Mongodb\Eloquent\Model)扩展了 Laravel 的 Eloquent Model 类,而这就是该belongsToMany方法所在的位置。

好的,这一定是它对您不起作用的原因,因为数组必须是字符串而不是 ObjectId。为什么是这样?因为这就是 Jenssegers 库的工作方式,所以它将 Id 保存为字符串。我也发现这种行为很奇怪,但这就是它的工作原理。请记住,您应该使用 Jenssegers 库关联对象,而不是通过在数据库中手动创建数据。你怎么能索引ID?只需在 MongoDB 中创建一个普通索引,例如tasks.createIndex({task_ids: 1}). 这是有关如何创建索引的文档:https ://docs.mongodb.com/manual/reference/method/db.collection.createIndex/ 。您还可以在迁移上创建索引,这里是关于迁移的文档,请务必阅读Jenssegers 关于迁移的注释

您可以tasks像这样访问 realtion:$employee->tasks;. 您可以通过获取与声明关系的方法同名的属性来访问关系,因此如果您有:

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

你得到的关系为$post->owner;。这是关于关系的文档:https ://laravel.com/docs/5.3/eloquent-relationships

于 2017-01-07T08:56:39.163 回答