我在version 3.1.0-alpha
中使用MongoDB库https://github.com/jenssegers/laravel-mongodb Laravel 5.3.28
我在MongoDB中有两个集合,我想与它们建立一个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] =>
)
)
)
在输出中,关系任务项为空。
有人能建议我关系b / w集合是否正确?
更新
我使用了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
}
答案 0 :(得分:2)
我理解你的另一个问题,任务可以属于很多员工,对吧?因此,您应该在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);
在输出中我们可以看到relations属性是一个数组:
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
方法所在的位置。
好的,这就是为什么它不适合你,因为数组必须是字符串而不是ObjectIds。为什么是这样?因为这就是Jenssegers库的工作方式,它将Ids保存为字符串。我也发现这种行为很奇怪,但这就是它的工作原理。请记住,应该使用Jenssegers库关联对象,而不是通过在数据库中手动创建数据。
你如何索引ID?只需在MongoDB中创建一个普通索引,如tasks.createIndex({task_ids: 1})
。以下是有关如何创建索引的文档:https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/。您还可以在迁移here are the docs on migrations上创建索引,请务必阅读Jenssegers notes on migrations。
您可以访问tasks
这样的实现:$employee->tasks;
。您可以通过获取与您声明其关系的方法名称相同的属性来访问关系,因此,如果您有:
class Post
{
public function owner()
{
return $this->belongsTo(User::class);
}
}
您获得的关系为$post->owner;
。以下是有关关系的文档:https://laravel.com/docs/5.3/eloquent-relationships