sql >> Databasteknik >  >> NoSQL >> MongoDB

Laravel MongoDB-biblioteket 'jenssegers/laravel-mongodb' har många relationer fungerar inte

Jag förstod av din andra fråga, att en uppgift kan tillhöra många anställda, eller hur? Så du bör använda belongsToMany relation i din Task modell. Även din exempel "uppgift"-samling visar att i ett dokument employee_id är en array och i det andra dokumentet är det ett ObjectId, när båda ska vara arrayer.

Hur som helst, jag har haft svårt att försöka komma på det här, men jag har sett att du inte kan använda hasMany som inversen av belongsToMany , eftersom belongsToMany skapar en array av ID, och hasMany fungerar inte bra med arrayer. Jag skulle säga att vi skulle behöva något som hasManyInArray , men när jag associerar en belongsToMany relation skapas "förälder"-dokumentet en array av ID, vilket får mig att tro att föräldern också ska använda belongsToMany även om det inte "hör till" utan faktiskt "har". Så när du skulle associera en anställd till en uppgift som denna:

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

"Employee"-dokumentet kommer att ha ett "task_ids"-attribut med det enda uppgifts-ID det ska ha. Så det verkar vara rätt väg att gå med Jenssegers:att använda belongsToMany i båda modellerna:

Laravel:Modell:Anställd:

<?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:Modell:Uppgift:

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

Och du skulle använda detta som:

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

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

Det enda med detta är att när du tittar på databasen kommer du att se att dina anställdas dokument har en array som heter "task_ids", och inuti den, id för den enda uppgift varje anställd har. Jag hoppas att detta hjälpte.

Bara några sidoanteckningar, du vet att du inte behöver definiera namnet på den primära nyckeln på varje modell, eller hur? Du behöver inte detta:

protected $primaryKey = '_id';

Du behöver inte heller definiera namnet på samlingen (dvs. protected $collection = 'employee'; ), såvida du inte verkligen vill att de ska vara i singular (som standard är de i plural).

Jag gick upp mitt i natten (det är 03:52 här) och kollade något på datorn och kollade sedan SÅ jag såg din fråga, jag hoppas den här gången jag svarade tillräckligt snabbt för dig, vi verkar vara i olika tidszoner.

Det här är dokumenten jag skapade för testning:

insamling av anställda

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

uppgiftsinsamling

{
    "_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 dessa dokument får jag den första medarbetaren så här:

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

Och i utgången kan vi se att relationsattributet är en array:

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 finns inte i filen du nämner eftersom den klassen (dvs. Jenssegers\Mongodb\Eloquent\Model ) utökar Laravels Eloquent Model-klass, och det är där belongsToMany metoden är.

Ok så det måste vara därför det inte fungerar för dig, eftersom arrayerna måste vara strängar istället för ObjectIds. Varför är detta? Eftersom det är så Jenssegers-biblioteket fungerar sparar det Ids som strängar. Jag har också tyckt att det här beteendet är konstigt, men det är så det fungerar. Kom ihåg att du förmodas att relatera objekt med hjälp av Jenssegers-biblioteket, inte genom att skapa data manuellt i databasen. Hur kan du indexera ID:n? Skapa bara ett normalt index i MongoDB, som tasks.createIndex({task_ids: 1}) . Här är dokumentationen om hur man skapar index:https://docs .mongodb.com/manual/reference/method/db.collection.createIndex/ . Du kan också skapa index för migrationer, här är dokumenten om migrationer , se till att läsa Jenssegers anteckningar om migrationer också.

Du kan komma åt tasks realtion så här:$employee->tasks; . Du kommer åt relationer genom att få en egenskap med samma namn på metoden som du deklarerade din relation med, så om du har:

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

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




  1. Mongoose går med i två samlingar och får refererade data i två egenskaper

  2. 6 bästa MapReduce Job Optimization Techniques

  3. Mongo-autentisering inuti Docker

  4. Autentiseringsfel vid anslutning till Mongo Atlas från Mule