sql >> データベース >  >> NoSQL >> MongoDB

LaravelMongoDBライブラリ'jenssegers/laravel-mongodb'hasMany関係が機能していません

    他の質問で、タスクは多くの従業員に属する可能性があることを理解しましたね。したがって、belongsToManyを使用する必要があります Taskの関係 モデル。また、「タスク」コレクションの例は、1つのドキュメントでemployee_id は配列であり、他のドキュメントでは、両方が配列である必要がある場合はObjectIdです。

    とにかく、私はこれを理解しようとするのに苦労しました、しかし私はあなたがhasManyを使うことができないのを見ました belongsToManyの逆として 、belongsToMany IDの配列を作成し、hasMany 配列ではうまく機能しません。 hasManyInArrayのようなものが必要だと思います 、ただし、belongsToManyを関連付けると 関係では、「親」ドキュメントはIDの配列を作成します。これにより、親もbelongsToManyを使用する必要があると思います。 それは「属している」のではなく、実際には「持っている」のですが。したがって、従業員を次のようなタスクに関連付ける場合:

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

    「employee」ドキュメントには、必要な唯一のタスクIDを持つ「task_ids」属性が含まれることになります。これがJenssegersを使用する方法のようです。belongsToManyを使用する 両方のモデルで:

    Laravel:モデル:従業員:

    <?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:モデル:タスク:

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

    そして、あなたはこれを次のように使うでしょう:

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

    これに関する唯一のことは、データベースを見ると、従業員のドキュメントに「task_ids」という配列があり、その中に各従業員が持つ唯一のタスクのIDがあることがわかります。これがお役に立てば幸いです。

    いくつかの補足として、各モデルで主キーの名前を定義する必要がないことをご存知ですか?これは必要ありません:

    protected $primaryKey = '_id';
    

    また、コレクションの名前を定義する必要はありません(つまり、protected $collection = 'employee'; )、本当に単数形にしたい場合を除きます(デフォルトでは複数形です)。

    私は真夜中に起きて(ここでは午前3時52分です)、コンピューターで何かをチェックしてから、あなたの質問を見たのでチェックしました。今回はあなたのために十分早く答えたと思います。私たちは異なるタイムゾーンにいるようです。

    テスト用に作成したドキュメントは次のとおりです。

    従業員コレクション

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

    タスクコレクション

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

    これらのドキュメントを使用して、次のような最初の従業員を取得します。

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

    そして、出力では、リレーション属性が配列であることがわかります。

    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 そのクラス(つまり、Jenssegers\Mongodb\Eloquent\Model)のため、メソッドは言及したファイルに含まれていません )LaravelのEloquent Modelクラスを拡張します。これは、belongsToManyに属する場所です。 方法は。

    配列はObjectIdではなく文字列である必要があるため、これが機能しない理由である必要があります。どうしてこれなの?これがJenssegersライブラリの仕組みであるため、IDを文字列として保存します。私もこの振る舞いが奇妙だと感じましたが、それがどのように機能するかです。 想定されていることを忘れないでください データベースにデータを手動で作成するのではなく、Jenssegersライブラリを使用してオブジェクトを関連付けるには、IDにインデックスを付けるにはどうすればよいですか。 tasks.createIndex({task_ids: 1})のように、MongoDBで通常のインデックスを作成するだけです。 。インデックスの作成方法に関するドキュメントは次のとおりです。 https:// docs .mongodb.com / manual / reference / method / db.collection.createIndex / 。移行に関するインデックスを作成することもできます。移行に関するドキュメントはこちら 、移行に関するJenssegersのメモ を必ずお読みください

    Taskにアクセスできます このような現実:$employee->tasks; 。リレーションを宣言したメソッドと同じ名前のプロパティを取得することでリレーションにアクセスします。したがって、次の場合:

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

    リレーションは$post->owner;として取得されます 。関係に関するドキュメントは次のとおりです。 https://laravel.com/docs/5.3/eloquent-relationships




    1. sparseの使用:trueはまだMongoErrorを取得しています:E11000重複キーエラー

    2. モジュール外でインポートステートメントを使用することはできません

    3. MongoDB 4.2.1-updateMany:エラー:更新操作ドキュメントにはアトミック演算子が含まれている必要があります

    4. MongoError:最初の接続でサーバーに接続できませんでした