MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Biblioteka Laravel MongoDB „jenssegers/laravel-mongodb” maWiele relacji nie działa

Z twojego drugiego pytania zrozumiałem, że zadanie może należeć do wielu pracowników, prawda? Powinieneś więc używać belongsToMany relacji w Twoim Task Model. Również twoja przykładowa kolekcja "task" pokazuje, że w jednym dokumencie employee_id jest tablicą, a w innym dokumencie jest to ObjectId, podczas gdy oba powinny być tablicami.

W każdym razie trudno mi było to rozgryźć, ale widziałem, że nie można użyć hasMany jako odwrotność belongsToMany , ponieważ belongsToMany tworzy tablicę identyfikatorów, a hasMany nie działa dobrze z tablicami. Powiedziałbym, że potrzebowalibyśmy czegoś takiego jak hasManyInArray , ale kiedy kojarzę belongsToMany relacji, dokument „rodzic” otrzymuje tablicę identyfikatorów, co prowadzi mnie do wniosku, że rodzic powinien również użyć belongsToMany nawet jeśli nie „należy”, ale faktycznie „ma”. Jeśli więc powiążesz pracownika z takim zadaniem:

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

Dokument „employee” będzie miał atrybut „task_ids” z jedynym identyfikatorem zadania, jaki powinien mieć. Tak więc wydaje się, że jest to droga z Jenssegers:użycie belongsToMany w obu modelach:

Laravel:Modelka:Pracownik:

<?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:Modelka:Zadanie:

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

I użyjesz tego tak:

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

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

Jedyną rzeczą w tym jest to, że kiedy spojrzysz na bazę danych, zobaczysz, że twoje dokumenty pracowników mają tablicę o nazwie "task_ids", a wewnątrz niej identyfikator jedynego zadania, jakie ma każdy pracownik. Mam nadzieję, że to pomogło.

Tylko kilka uwag, wiesz, że nie musisz definiować nazwy klucza podstawowego w każdym modelu, prawda? Nie potrzebujesz tego:

protected $primaryKey = '_id';

Ponadto nie musisz określać nazwy kolekcji (tj. protected $collection = 'employee'; ), chyba że naprawdę chcesz, aby były w liczbie pojedynczej (domyślnie w liczbie mnogiej).

Wstałem w środku nocy (tutaj jest 3:52 nad ranem) i sprawdziłem coś na komputerze, a następnie sprawdziłem SO i zobaczyłem twoje pytanie, mam nadzieję, że tym razem odpowiedziałem wystarczająco szybko, wydaje się, że jesteśmy w różnych strefach czasowych.

Oto dokumenty, które stworzyłem do testowania:

odbiór pracowników

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

kolekcja zadań

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

Dzięki tym dokumentom mam pierwszego pracownika w ten sposób:

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

A na wyjściu widzimy, że atrybut relations jest tablicą:

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 metody nie ma we wspomnianym pliku, ponieważ ta klasa (np. Jenssegers\Mongodb\Eloquent\Model ) rozszerza klasę Eloquent Model Laravela i właśnie tam belongsToMany metoda jest.

Ok, więc to musi być powód, dla którego to nie działa, ponieważ tablice muszą być ciągami zamiast identyfikatorów ObjectId. Dlaczego to? Ponieważ tak działa biblioteka Jenssegers, zapisuje identyfikatory jako ciągi. Również uważam to zachowanie za dziwne, ale tak to działa. Pamiętaj, że podobno do powiązania obiektów za pomocą biblioteki Jenssegers, a nie poprzez ręczne tworzenie danych w bazie danych.Jak można indeksować identyfikatory? Po prostu utwórz normalny indeks w MongoDB, taki jak tasks.createIndex({task_ids: 1}) . Oto dokumentacja dotycząca tworzenia indeksów:https://docs .mongodb.com/manual/reference/method/db.collection.createIndex/ . Możesz także tworzyć indeksy dotyczące migracji, tutaj znajdują się dokumenty dotyczące migracji , koniecznie przeczytaj notatki Jenssegera dotyczące migracji też.

Możesz uzyskać dostęp do tasks relacja taka:$employee->tasks; . Dostęp do relacji uzyskujesz, pobierając właściwość o tej samej nazwie, co metoda, za pomocą której zadeklarowałeś relację, więc jeśli:

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

Otrzymasz relację jako $post->owner; . Oto dokumentacja relacji:https://laravel.com/docs/5.3/eloquent-relationships




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB Nie można znaleźć wpisu, określając ts.t (ts jest typem sygnatury czasowej)

  2. Aktualizacja tablicy w MongoDB za pomocą sterownika Java

  3. Wybierz pasujący element tablicy i zwróć wybrane pola

  4. Usuwanie osieroconych plików z GridFS

  5. Pomiń oprogramowanie pośredniczące ze znacznikami czasu w przypadku niektórych aktualizacji w Mongoose