sql >> Database teknologi >  >> NoSQL >> MongoDB

Laravel MongoDB-biblioteket 'jenssegers/laravel-mongodb' har Mange forhold fungerer ikke

Jeg forstod på dit andet spørgsmål, at en opgave kan tilhøre mange medarbejdere, ikke? Så du bør bruge belongsToMany forhold i din Task model. Også din eksempel "opgave" samling viser, at i ét dokument employee_id er et array, og i det andet dokument er det et ObjectId, når begge skal være arrays.

Jeg har i hvert fald haft svært ved at finde ud af det, men jeg har set, at du ikke kan bruge hasMany som omvendt af belongsToMany , fordi belongsToMany opretter en række id'er, og hasMany fungerer ikke godt med arrays. Jeg vil sige, at vi ville have brug for noget som hasManyInArray , men når jeg tilknytter en belongsToMany forhold, bliver "forælder"-dokumentet oprettet en række id'er, hvilket får mig til at tro, at forælderen også skal bruge belongsToMany selvom det ikke "hører til", men faktisk "har". Så når du vil knytte en medarbejder til en opgave som denne:

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

"Employee"-dokumentet vil ende med at have en "task_ids"-attribut med det eneste opgave-id, det skal have. Så det ser ud til at være vejen med Jenssegers:at bruge belongsToMany i begge modeller:

Laravel:Model:Medarbejder:

<?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:Opgave:

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

Og du ville bruge dette som:

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

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

Det eneste ved dette er, at når du ser på databasen, vil du se, at dine medarbejderdokumenter har et array kaldet "task_ids", og inde i det, id'et for den eneste opgave, hver medarbejder har. Jeg håber, at dette hjalp.

Bare nogle sidebemærkninger, du ved, at du ikke behøver at definere navnet på den primære nøgle på hver model, vel? Du behøver ikke dette:

protected $primaryKey = '_id';

Du behøver heller ikke at definere navnet på samlingen (dvs. protected $collection = 'employee'; ), medmindre du virkelig ønsker, at de skal være i ental (som standard er de i flertal).

Jeg stod op midt om natten (det er 03:52 her) og tjekkede noget på computeren og tjekkede så SÅ jeg så dit spørgsmål, jeg håber denne gang, at jeg svarede hurtigt nok for dig, vi ser ud til at være i forskellige tidszoner.

Dette er de dokumenter, jeg oprettede til test:

medarbejderindsamling

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

opgavesamling

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

Med disse dokumenter får jeg den første medarbejder sådan her:

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

Og i outputtet kan vi se, at relationsattributten er en matrix:

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 metoden er ikke i den fil, du nævner, fordi den klasse (dvs. Jenssegers\Mongodb\Eloquent\Model ) udvider Laravels Eloquent Model-klasse, og det er her belongsToMany metode er.

Ok, så det må være derfor, det ikke virker for dig, fordi arrays skal være strenge i stedet for ObjectIds. Hvorfor er det? For det er sådan Jenssegers bibliotek fungerer, det gemmer Id'erne som strenge. Jeg har også fundet denne adfærd mærkelig, men sådan fungerer det. Husk, at du formodes at relatere objekter ved hjælp af Jenssegers-biblioteket, ikke ved at oprette dataene manuelt i databasen. Hvordan kan du indeksere id'erne? Du skal bare oprette et normalt indeks i MongoDB, såsom tasks.createIndex({task_ids: 1}) . Her er dokumentationen til, hvordan du opretter indekser:https://docs .mongodb.com/manual/reference/method/db.collection.createIndex/ . Du kan også oprette indekser om migrationer, her er dokumenterne om migrationer , sørg for at læse Jenssegers noter om migrationer også.

Du kan få adgang til tasks realtion som denne:$employee->tasks; . Du får adgang til relationer ved at få en ejendom med samme navn som den metode, du erklærede dit forhold til, så hvis du har:

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

Du får relationen som $post->owner; . Her er dokumentationen om relationer:https://laravel.com/docs/5.3/eloquent-relationships




  1. Vil en Mongo $nær returnere dokumenter, for hvilke ethvert punkt i et MultiPoint er inden for rækkevidde?

  2. Hvordan modellerer man, når man bruger Spring data mongo og Spring data elasticearch?

  3. Sådan gør du:Administrer HBase-data via Hue

  4. Mongoose near(...)-forespørgsel på 2dsphere-indekseret felt returnerer ikke gyldige resultater