sql >> Databáze >  >> NoSQL >> MongoDB

Laravel MongoDB knihovna 'jenssegers/laravel-mongodb' hasMany vztah nefunguje

Z vaší další otázky jsem pochopil, že úkol může patřit mnoha zaměstnancům, že? Měli byste tedy používat belongsToMany vztah ve vašem Task Modelka. Také vaše vzorová sbírka „úkolů“ ukazuje, že v jednom dokumentu je employee_id je pole a v druhém dokumentu je to ObjectId, když obě by měly být pole.

Každopádně jsem měl problém to zjistit, ale viděl jsem, že nemůžete použít hasMany jako opak k belongsToMany , protože belongsToMany vytvoří pole id a hasMany nefunguje dobře s poli. Řekl bych, že bychom potřebovali něco jako hasManyInArray , ale když přidružím belongsToMany vztahu, "rodičovský" dokument se vytvoří pole id, což mě vede k názoru, že nadřazený by měl také používat belongsToMany i když to "nepatří", ale ve skutečnosti "má". Takže když byste přidružili zaměstnance k úkolu, jako je tento:

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

Dokument „zaměstnanec“ bude mít atribut „task_ids“ s jediným id úkolu, který by měl mít. Zdá se tedy, že to je způsob, jak jít s Jenssegersem:použít belongsToMany v obou modelech:

Laravel:Model:Zaměstnanec:

<?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:Úkol:

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

A použili byste toto jako:

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

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

Jediná věc na tom je, že když se podíváte do databáze, uvidíte, že vaše dokumenty zaměstnanců mají pole nazvané „task_ids“ a uvnitř něj je id jediného úkolu, který každý zaměstnanec má. Doufám, že to pomohlo.

Jen několik poznámek, víte, že u každého modelu nemusíte definovat název primárního klíče, že? Toto nepotřebujete:

protected $primaryKey = '_id';

Také nemusíte definovat název kolekce (tj. protected $collection = 'employee'; ), pokud opravdu nechcete, aby byly v jednotném čísle (ve výchozím nastavení jsou v množném čísle).

Vstal jsem uprostřed noci (je tady 3:52) a zkontroloval jsem něco v počítači a pak jsem to zkontroloval, takže jsem viděl vaši otázku, doufám, že tentokrát jsem vám odpověděl dostatečně brzy, zdá se, že jsme v různých časových pásmech.

Toto jsou dokumenty, které jsem vytvořil pro testování:

sbírka zaměstnanců

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

kolekce úkolů

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

S těmito dokumenty získám prvního zaměstnance takto:

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

A ve výstupu můžeme vidět, že atribut relace je pole:

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 metoda není v souboru, který zmiňujete, protože tato třída (tj. Jenssegers\Mongodb\Eloquent\Model ) rozšiřuje třídu Laravel's Eloquent Model, a to je místo, kde belongsToMany metoda je.

Dobře, takže to musí být důvod, proč to pro vás nefunguje, protože pole musí být řetězce namísto ObjectId. Proč je to? Protože tak knihovna Jenssegers funguje, ukládá ID jako řetězce. Toto chování mi také přišlo divné, ale tak to funguje. Pamatujte si, že se předpokládá spojovat objekty pomocí knihovny Jenssegers, nikoli ručním vytvářením dat v databázi. Jak můžete indexovat ID? Stačí vytvořit normální index v MongoDB, například tasks.createIndex({task_ids: 1}) . Zde je dokumentace, jak vytvořit indexy:https://docs .mongodb.com/manual/reference/method/db.collection.createIndex/ . Můžete také vytvářet indexy o migracích, zde jsou dokumenty o migracích , nezapomeňte si přečíst Poznámky Jenssegers o migracích taky.

Máte přístup k tasks relaci takto:$employee->tasks; . Ke vztahům se dostanete tak, že získáte vlastnost se stejným názvem jako metoda, kterou jste deklarovali svůj vztah, takže pokud máte:

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

Získáte vztah jako $post->owner; . Zde je dokumentace o vztazích:https://laravel.com/docs/5.3/eloquent-relationships




  1. Připojení k MongoDB Atlas z funkcí firebase

  2. Jak obejít tento asynchronní problém MongoDB/Node?

  3. mongoimport CSV s pymongo

  4. UnhandledPromiseRejectionWarning:MongooseServerSelectionError