$ lookup с php mongodb - PullRequest
       29

$ lookup с php mongodb

0 голосов
/ 26 сентября 2018

У меня есть таблица ученика в mongo db вроде

      {
       "_id": ObjectId("5baa85f61d7859401000002a"),
        "Name": "Bella Dave",
         "RollNo": 12,
        "Class": "Ist",
        "TransportDetails": [
         {
            "RouteId": ObjectId("5baa93a21d7859401000002b"),
            "StopId": "abc123",
            "Status": "Inactive" 
         },
         {
            "RouteId": ObjectId("5baa818d1d78594010000029"),
            "StopId": "abc456",
            "Status": "Active" 
         } 
       ] 
     }

У меня есть таблица маршрутов как

  {
     "Name": "New york City",
     "StopDetails": [
      {
        "StopId": "abc123",
        "Name": "Block no 1"
      },
     {
       "StopId": "abc567",
       "Name": "Block no 2"
     }
   ]        

Я написал ниже агрегационный запрос типа

       $cursor = $this->db->TblStudent->aggregate([
    [
        '$addFields' => [
            'ActiveRouteId' => [
                '$map' => [
                    'input' => '$TransportDetails',
                    'as' => 'item',
                    'in' => [
                        '$cond' => [
                            ['$eq' => ['$$item.Status', "Active"]],
                            '$$item.RouteId',
                            false
                        ]
                    ]
                ]
            ]
        ]
    ],
     [
        '$addFields' => [
            'ActiveStopId' => [
                '$map' => [
                    'input' => '$TransportDetails',
                    'as' => 'item',
                    'in' => [
                        '$cond' => [
                            ['$eq' => ['$$item.Status', "Active"]],
                            '$$item.StopId',
                            false
                        ]
                    ]
                ]
            ]
        ]
    ],
     array(
            '$lookup' => array(
                'from' => 'TblRoute',
                'localField' => 'ActiveRouteId',
                'foreignField' => '_id',
                'as' => 'RouteDetails'
            )
        ),
     array(
            '$lookup' => array(
                'from' => 'TblRoute',
                'localField' => 'ActiveStopId',
                'foreignField' => 'StopDetails.StopId',
                'as' => 'StopDetails'
            )
        ),
     ])->toArray();

    return $cursor;

По сути, мне нужно получить активную информацию о маршрутах и ​​остановках вместе с данными учеников.Итак, я успешно извлек ActiveRouteId и ActiveStopId, используя операторы $ addFields и $ map.Основываясь на ActiveRouteId, я делаю поиск $ $ для получения информации об активном маршруте.Я успешно получаю это во встроенном документе "RouteDetails".Теперь я выпускаю в строке

            array(
            '$lookup' => array(
                'from' => 'TblRoute',
                'localField' => 'ActiveStopId',
                'foreignField' => 'StopDetails.StopId',
                'as' => 'StopDetails'
            )
        ),

Этот поиск ничего не получает.Пожалуйста помоги!!!

Возможно ли найти маршрут и остановить информацию вместе.Я имею в виду, что в таблице маршрутов есть много других встроенных документов, если есть возможность извлечь требуемый встроенный документ, например

      RouteDetails: [      
     "Name": "New york City",
     "StopDetails": [
      {
        "StopId": "abc123",
        "Name": "Block no 1"
      }
     ]

1 Ответ

0 голосов
/ 26 сентября 2018

Вы можете попробовать ниже агрегации

TblStudent.aggregate([
  [ "$addFields"=> [
    "TransportDetails"=> [
      "$cond"=> [
        "if"=> [
          "$ne"=> [ [ "$type"=> "$TransportDetails" ], "array" ]
        ],
        "then"=> [],
        "else"=> "$TransportDetails"
      ]
    ]
  ]],
  [ "$addFields"=> [
    "ActiveRouteId"=> [
      "$filter"=> [
        "input"=> "$TransportDetails",
        "as"=> "item",
        "cond"=> [ "$eq"=> ["$$item.Status", "Active"] ]
      ]
    ]
  ]],
  [ "$lookup"=> [
    "from"=> "TblRoute",
    "let"=> [ "activeRouteId"=> "$ActiveRouteId.RouteId" ],
    "pipeline"=> [
      [ "$match"=> [ "$expr"=> [ "$in"=> ["$_id", "$$activeRouteId"] ]]]
    ],
    "as"=> "RouteDetails"
  ]],
  [ "$lookup"=> [
    "from"=> "TblRoute",
    "let"=> [ "activeStopId"=> "$ActiveRouteId.StopId" ],
    "pipeline"=> [
      [ "$unwind"=> "$StopDetails" ],
      [ "$match"=> [ "$expr"=> [ "$in"=> ["$StopDetails.StopId", "$$activeStopId"] ]]],
    ],
    "as"=> "StopDetails"
  ]]
])

Похож на javascript

TblStudent.aggregate([
  { "$addFields": {
    "TransportDetails": {
      "$cond": {
        "if": {
          "$ne": [ { "$type": "$TransportDetails" }, "array" ]
        },
        "then": [],
        "else": "$TransportDetails"
      }
    }
  }},
  { "$addFields": {
    "ActiveRouteId": {
      "$filter": {
        "input": "$TransportDetails",
        "as": "item",
        "cond": { "$eq": ["$$item.Status", "Active"] }
      }
    }
  }},
  { "$lookup": {
    "from": "TblRoute",
    "let": { "activeRouteId": "$ActiveRouteId.RouteId" },
    "pipeline": [
      { "$match": { "$expr": { "$in": ["$_id", "$$activeRouteId"] }}}
    ],
    "as": "RouteDetails"
  }},
  { "$lookup": {
    "from": "TblRoute",
    "let": { "activeStopId": "$ActiveRouteId.StopId" },
    "pipeline": [
      { "$unwind": "$StopDetails" },
      { "$match": { "$expr": { "$in": ["$StopDetails.StopId", "$$activeStopId"] }}},
    ],
    "as": "StopDetails"
  }}
])

Дает мне следующий вывод

/* 1 */
{
    "_id" : ObjectId("5baa85f61d7859401000002a"),
    "Name" : "Bella Dave",
    "RollNo" : 12,
    "Class" : "Ist",
    "TransportDetails" : [ 
        {
            "RouteId" : ObjectId("5baa93a21d7859401000002b"),
            "StopId" : "abc123",
            "Status" : "Inactive"
        }, 
        {
            "RouteId" : ObjectId("5baa818d1d78594010000029"),
            "StopId" : "abc456",
            "Status" : "Active"
        }
    ],
    "ActiveRouteId" : [ 
        {
            "RouteId" : ObjectId("5baa818d1d78594010000029"),
            "StopId" : "abc456",
            "Status" : "Active"
        }
    ],
    "routeDetails" : [ 
        {
            "_id" : ObjectId("5baa818d1d78594010000029"),
            "Name" : "New york City",
            "StopDetails" : [ 
                {
                    "StopId" : "abc123",
                    "Name" : "Block no 1"
                }, 
                {
                    "StopId" : "abc567",
                    "Name" : "Block no 2"
                }
            ]
        }
    ],
    "StopDetails" : [ 
        {
            "_id" : ObjectId("5baa93a21d7859401000002b"),
            "Name" : "New york City",
            "StopDetails" : {
                "StopId" : "abc456",
                "Name" : "Block no 2"
            }
        }
    ]
}
...