Doctrine2: хук PreFlush делает тайм-аут

MongoDB не разрешает объединения, но вы можете использовать плагины для его обработки. Проверьте плагин mongo-join. Это лучшее, и я уже использовал его. Вы можете установить его с помощью npm прямо следующим образом npm install mongo-join. Вы можете проверить полную документацию с примерами .

(++) действительно полезный инструмент, когда нам нужно объединить (N) коллекции

(- ), мы можем применять условия только на верхнем уровне запроса

Пример

var Join = require('mongo-join').Join, mongodb = require('mongodb'), Db = mongodb.Db, Server = mongodb.Server;
db.open(function (err, Database) {
    Database.collection('Appoint', function (err, Appoints) {

        /* we can put conditions just on the top level */
        Appoints.find({_id_Doctor: id_doctor ,full_date :{ $gte: start_date },
            full_date :{ $lte: end_date }}, function (err, cursor) {
            var join = new Join(Database).on({
                field: '_id_Doctor', // <- field in Appoints document
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            }).on({
                field: '_id_Patient', // <- field in Appoints doc
                to: '_id',         // <- field in User doc. treated as ObjectID automatically.
                from: 'User'  // <- collection name for User doc
            })
            join.toArray(cursor, function (err, joinedDocs) {

                /* do what ever you want here */
                /* you can fetch the table and apply your own conditions */
                .....
                .....
                .....


                resp.status(200);
                resp.json({
                    "status": 200,
                    "message": "success",
                    "Appoints_Range": joinedDocs,


                });
                return resp;


            });

    });

0
задан Michal Takáč 17 January 2019 в 14:16
поделиться

2 ответа

Причина в рекурсии: вы звоните $em->flush(); от абонента, EntityManager вводит flush, запускает событие preFlush, которое вызывает ваш обработчик, который снова вызывает $em->flush() и т. Д.

IIRC preFlush вызывается перед вычислением набора изменений, так что простого обновления вашей сущности новым значением должно быть достаточно, чтобы Doctrine обнаружила указанное изменение.

0
ответ дан malarzm 17 January 2019 в 14:16
поделиться

Итак, я смог найти решение после нескольких часов борьбы.

Оказывается, мне не нужно ни настаивать, ни сбрасывать изменения. Решение состоит в том, чтобы использовать Unit of Work для пересчета изменений в $ parent, а затем доктрина сбросит их самостоятельно. Мне также пришлось изменить способ подсчета продуктов, так как на этапе предварительной проверки изменения еще нет в базе данных, поэтому запрос не будет работать должным образом. Вот почему я считаю их вручную, обходя дерево отношений.

Вот пример кода.

public function preFlush(Room $room, PreFlushEventArgs $args)
  {
    $em = $args->getEntityManager();
    $numOfProducts = 0;
    $parent = $room->getStore()->getParent();
    foreach($parent->getStores() as $store) {
      foreach($store->getRooms() as $room) {
        $numOfServices += count($room->getProducts());
      }
    }
    $parent->setNumberOfProducts($numOfProducts);
    $classMetadata = $em->getClassMetadata(get_class($parent));
    $em->getUnitOfWork()->computeChangeSet($classMetadata, $parent);
  }
0
ответ дан Michal Takáč 17 January 2019 в 14:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: