Запрос полей массива документа в PHP MongoDB с использованием фильтра и параметров - PullRequest
0 голосов
/ 25 января 2020

Я использую PHP MongoDB \ Driver \ Manager и хочу сделать запрос, создав MongoDB \ Driver \ Query.

Итак, у меня есть следующий дизайн коллекции:

{
    "_comment": "Board",
    "_id": "3",
    "player": "42",
    "moves": [{
        "_id": "1",
        "piece": "b3rw4",
        "from_pos": "E2",
        "to_pos": "E4"
    }]
}

Как я могу запросить эту коллекцию, чтобы получить для всех досок определенного c игрока все ходы с min (id)? Это означает, что я сначала хочу отфильтровать все доски, чтобы получить только доски с идентификатором игрока. Затем я хочу найти все поля "ходов" на этой доске, где я хочу, чтобы мин (_id) этого поля "ходов".

В настоящее время у меня есть этот запрос:

$filter = ['player' => '93'];
$options = [
    'projection' => ['_id' => 0,
                     'moves' => 1]
];
$query = new MongoDB\Driver\Query($filter, $options);

Это приводит к нахождению всех массивов "ходов" игроком 93.

Как я могу отфильтровать все эти поля "ходов", получая только ходы с min (_id)?

1 Ответ

0 голосов
/ 26 января 2020

Хорошо, так что я понял это. Мне просто пришлось использовать конвейер агрегации.

Вот команда оболочки, которая дает ожидаемый результат:

db.boards.aggregate( [
    {
     $match: {'player': '93'}
    },
    {
     $unwind: {path: '$moves'}
    },
    {
     $group:
       {
         _id: '$_id',
         first_move: { $min: '$moves._id' },
         from_pos : { $first: '$moves.from_pos' },
         to_pos: { $first: '$moves.to_pos' }
       }    
    }
])

Вот соответствующий PHP код MongoDB с использованием Command и aggregate:

$command = new MongoDB\Driver\Command([
    'aggregate' => 'boards',
    'pipeline' => [
        ['$match' => ['player' => '93']],
        ['$unwind' => '$moves'],
        ['$group' => ['_id' => '$_id',
                      'firstMove' => ['$min' => '$moves._id'],
                      'from_pos' => ['$first' => '$moves.from_pos'],
                      'to_pos' => ['$first' => '$moves.to_pos']
                     ]
        ]
    ],
    'cursor' => new stdClass,
]);

$manager = new MongoDB\Driver\Manager($url);
$cursor = $manager->executeCommand('db', $command);
...