sql >> Database >  >> NoSQL >> MongoDB

Laravel MongoDB-bibliotheek 'jenssegers/laravel-mongodb' hasMany-relatie werkt niet

Ik begreep uit je andere vraag, dat een taak van veel medewerkers kan zijn, toch? U zou dus belongsToMany . moeten gebruiken relatie in je Task model. Ook uw voorbeeldverzameling "taak" laat zien dat in één document employee_id is een array en in het andere document is het een ObjectId, terwijl beide arrays zouden moeten zijn.

Hoe dan ook, ik heb moeite gehad om dit uit te zoeken, maar ik heb gezien dat je hasMany niet kunt gebruiken als het omgekeerde van belongsToMany , omdat belongsToMany maakt een array van id's, en hasMany werkt niet goed met arrays. Ik zou zeggen dat we iets nodig hebben als hasManyInArray , maar wanneer ik een belongsToMany associate associeer relatie, wordt in het "ouder"-document een array van id's gemaakt, wat me doet denken dat de ouder ook belongsToMany moet gebruiken ook al "behoort het niet tot" maar eigenlijk "heeft". Dus wanneer u een medewerker aan een taak als deze zou koppelen:

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

Het "employee"-document krijgt uiteindelijk het attribuut "task_ids" met het enige taak-ID dat het zou moeten hebben. Dus dat lijkt de juiste weg te zijn met Jenssegers:om belongsToMany te gebruiken in beide modellen:

Laravel:Model:Medewerker:

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

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

En je zou dit als volgt gebruiken:

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

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

Het enige hieraan is dat wanneer u naar de database kijkt, u zult zien dat uw werknemersdocumenten een array hebben met de naam "task_ids", en daarin de id van de enige taak die elke werknemer heeft. Ik hoop dat dit heeft geholpen.

Gewoon wat kanttekeningen, je weet dat je de naam van de primaire sleutel niet op elk model hoeft te definiëren, toch? Dit heb je niet nodig:

protected $primaryKey = '_id';

Ook hoeft u de naam van de collectie niet te definiëren (d.w.z. protected $collection = 'employee'; ), tenzij u echt wilt dat ze in het enkelvoud staan ​​(standaard staan ​​ze in het meervoud).

Ik stond midden in de nacht op (het is hier 3:52AM) en controleerde iets op de computer en controleerde toen DUS en zag je vraag, ik hoop dat ik deze keer snel genoeg voor je heb geantwoord, we lijken in verschillende tijdzones te zijn.

Dit zijn de documenten die ik heb gemaakt om te testen:

werknemersverzameling

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

taakverzameling

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

Met deze documenten krijg ik de eerste medewerker zo:

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

En in de uitvoer kunnen we zien dat het relation-attribuut een array is:

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

De belongsToMany methode staat niet in het bestand dat u noemt, omdat die klasse (d.w.z. Jenssegers\Mongodb\Eloquent\Model ) breidt de Eloquent Model-klasse van Laravel uit, en dat is waar de belongsToMany methode is.

Oké, dus dat moet de reden zijn waarom het niet voor jou werkt, omdat de arrays strings moeten zijn in plaats van ObjectIds. Waarom is dit? Omdat dat is hoe de Jenssegers-bibliotheek werkt, slaat het de Id's op als strings. Ik heb dit gedrag ook vreemd gevonden, maar zo werkt het. Onthoud dat je verondersteld wordt om objecten te relateren met behulp van de Jenssegers-bibliotheek, niet door de gegevens handmatig in de database te maken. Hoe kunt u de id's indexeren? Maak gewoon een normale index in MongoDB, zoals tasks.createIndex({task_ids: 1}) . Hier is de documentatie over het maken van indexen:https://docs .mongodb.com/manual/reference/method/db.collection.createIndex/ . U kunt ook indexen over migraties maken, hier zijn de documenten over migraties , zorg ervoor dat u Jenssegers-opmerkingen over migraties leest ook.

Je hebt toegang tot de tasks relatie als deze:$employee->tasks; . U krijgt toegang tot relaties door een eigenschap te krijgen met dezelfde naam als de methode waarmee u uw relatie hebt aangegeven, dus als u:

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

Je krijgt de relatie als $post->owner; . Hier is de documentatie over relaties:https://laravel.com/docs/5.3/eloquent-relationships




  1. Hoe documenten uit te sluiten van zoekresultaten met velden die niet aanwezig zijn in de zoekopdracht?

  2. kan geen rustgesprek voeren

  3. MongoDB-fout:kan geen herschrijfbare schrijfbewerkingen gebruiken met limiet =0

  4. Hoe beheer ik MongoDB-verbindingen in een Node.js-webtoepassing?