MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Thư viện Laravel MongoDB 'jenssegers / laravel-mongodb' có Nhiều mối quan hệ không hoạt động

Tôi đã hiểu câu hỏi khác của bạn, rằng một nhiệm vụ có thể thuộc về nhiều nhân viên, phải không? Vì vậy, bạn nên sử dụng belongsToMany mối quan hệ trong Task của bạn người mẫu. Ngoài ra, bộ sưu tập "nhiệm vụ" mẫu của bạn cho thấy rằng trong một tài liệu employee_id là một mảng và trong tài liệu khác, nó là một ObjectId, khi cả hai phải là mảng.

Dù sao thì, tôi đã gặp khó khăn khi cố gắng tìm ra điều này, nhưng tôi thấy rằng bạn không thể sử dụng hasMany như là nghịch đảo của belongsToMany , bởi vì belongsToMany tạo một mảng id và hasMany không hoạt động tốt với mảng. Tôi muốn nói rằng chúng ta cần một cái gì đó như hasManyInArray , nhưng khi tôi liên kết một belongsToMany mối quan hệ, tài liệu "cha" được tạo một mảng id, điều này khiến tôi nghĩ rằng nguồn gốc cũng nên sử dụng belongsToMany mặc dù nó không "thuộc về" nhưng thực ra là "có". Vì vậy, khi bạn liên kết một nhân viên với một nhiệm vụ như thế này:

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

Tài liệu "nhân viên" sẽ có thuộc tính "task_ids" với id nhiệm vụ duy nhất mà nó phải có. Vì vậy, đó dường như là cách để đi với Jenssegers:sử dụng belongsToMany trong cả hai mô hình:

Laravel:Mô hình:Nhân viên:

<?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:Model:Task:

<?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);
    }
}

Và bạn sẽ sử dụng nó như sau:

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

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

Điều duy nhất về điều này là khi bạn nhìn vào cơ sở dữ liệu, bạn sẽ thấy rằng các tài liệu nhân viên của bạn có một mảng được gọi là "task_ids", và bên trong nó là id của nhiệm vụ duy nhất mà mỗi nhân viên có. Tôi hy vọng điều này sẽ hữu ích.

Chỉ cần một số lưu ý phụ, bạn biết rằng bạn không cần phải xác định tên của khóa chính trên mỗi mô hình, phải không? Bạn không cần cái này:

protected $primaryKey = '_id';

Ngoài ra, bạn không phải xác định tên của bộ sưu tập (tức là protected $collection = 'employee'; ), trừ khi bạn thực sự muốn chúng ở số ít (theo mặc định chúng ở số nhiều).

Tôi thức dậy vào lúc nửa đêm (ở đây là 3:52 sáng) và kiểm tra một cái gì đó trên máy tính và sau đó kiểm tra SO an thấy câu hỏi của bạn, tôi hy vọng lần này tôi trả lời đủ sớm cho bạn, chúng ta có vẻ ở múi giờ khác nhau.

Đây là những tài liệu tôi đã tạo để thử nghiệm:

bộ sưu tập nhân viên

{
    "_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"
    ]
}

bộ sưu tập nhiệm vụ

{
    "_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"
    ]
}

Với những tài liệu này, tôi có được nhân viên đầu tiên như thế này:

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

Và trong đầu ra, chúng ta có thể thấy thuộc tính quan hệ là một mảng:

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 [▶]
          ]
        }
      ]
    }
  ]
}

belongsToMany phương thức không có trong tệp bạn đề cập vì lớp đó (tức là Jenssegers\Mongodb\Eloquent\Model ) mở rộng lớp Eloquent Model của Laravel và đó là nơi belongsToMany phương pháp là.

Ok vì vậy đó phải là lý do tại sao nó không hoạt động cho bạn, bởi vì các mảng phải là chuỗi thay vì ObjectIds. Tại sao thế này? Bởi vì đó là cách thư viện Jenssegers hoạt động, nó lưu các id dưới dạng chuỗi. Tôi cũng thấy hành vi này kỳ lạ, nhưng đó là cách nó hoạt động. Hãy nhớ rằng bạn được cho là để liên kết các đối tượng bằng cách sử dụng thư viện Jenssegers, không phải bằng cách tạo dữ liệu theo cách thủ công trong cơ sở dữ liệu. Làm thế nào bạn có thể lập chỉ mục id? Chỉ cần tạo một chỉ mục bình thường trong MongoDB, như tasks.createIndex({task_ids: 1}) . Đây là tài liệu về cách tạo chỉ mục: https:// docs .mongodb.com / manual / reference / method / db.collection.createIndex / . Bạn cũng có thể tạo chỉ mục khi di chuyển, đây là tài liệu về di chuyển , hãy nhớ đọc ghi chú của Jenssegers về việc di chuyển quá.

Bạn có thể truy cập tasks nhận thức như thế này:$employee->tasks; . Bạn truy cập các quan hệ bằng cách lấy một thuộc tính có cùng tên của phương thức mà bạn đã khai báo mối quan hệ của mình, vì vậy nếu bạn có:

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

Bạn nhận được mối quan hệ là $post->owner; . Đây là tài liệu về quan hệ: https://laravel.com/docs/5.3/eloquent-relationships




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB tổng hợp các đường ống với đối tượng được liên kết

  2. Hiệu suất MongoDB - có nhiều cơ sở dữ liệu

  3. Nhóm Mongoose và số lượng

  4. $ addFields khi không tìm thấy $ phù hợp

  5. NODE.JS:FATAL ERROR- JS Phân bổ không thành công - xử lý hết bộ nhớ trong khi phân tích cú pháp các tệp excel lớn