Если ActiveRecord MongoDB отдает массивы вместо моделей, чаще всего причина в asArray(), использовании низкоуровневого запроса к коллекции или неправильной модели. Для Yii2 MongoDB ActiveRecord результат Model::find()->all() должен возвращать объекты модели, если вы не включали режим массивов
Модель должна наследоваться от yii\mongodb\ActiveRecord:
use yii\mongodb\ActiveRecord;
class Product extends ActiveRecord
{
public static function collectionName()
{
return 'products';
}
public function attributes()
{
return ['_id', 'title', 'price'];
}
}
Получение моделей:
$products = Product::find()
->where(['active' => true])
->all();
foreach ($products as $product) {
echo $product->title;
}
Здесь $product должен быть объектом Product
Проверьте asArray
Если в запросе есть asArray(), результат будет массивом:
$products = Product::find()
->where(['active' => true])
->asArray()
->all();
Чтобы вернуть модели, уберите asArray() или явно выключите его:
$products = Product::find()
->where(['active' => true])
->asArray(false)
->all();
Не путайте ActiveRecord и collection
Если вы делаете запрос через коллекцию напрямую, результат будет ближе к массивам документов:
$rows = Yii::$app->mongodb
->getCollection('products')
->find(['active' => true]);
Для моделей используйте Product::find(), а не прямой доступ к коллекции
one и all
one() возвращает одну модель или null:
$product = Product::find()->where(['_id' => $id])->one();
all() возвращает массив моделей:
$products = Product::find()->all();
Важно: all() всегда возвращает PHP-массив как контейнер, но элементы внутри должны быть объектами модели. Если вы ожидаете «не массив вообще», используйте one() для одного документа
Как проверить тип
var_dump($products[0] instanceof Product);
Если результат true, ActiveRecord вернул модель. Если false, смотрите asArray, тип запроса и наследование класса
Что делать с агрегациями
Если вы используете aggregation через MongoDB collection, результат часто будет массивом данных, а не ActiveRecord-моделью. Это нормально: aggregation возвращает вычисленный результат, который может не совпадать со структурой модели
Если вам нужны именно модели, сначала получите id документов, а потом запросите их через ActiveRecord:
$ids = array_column($rows, '_id');
$models = Product::find()
->where(['_id' => $ids])
->all();
Так вы отделяете вычисления от загрузки моделей
Частые ошибки
Используют asArray
asArray() нужен для легкого результата без методов модели. Для объектов модели его убирают
Запрашивают коллекцию напрямую
Низкоуровневый доступ полезен для особых запросов, но он не обязан возвращать ActiveRecord-модели
Не описали attributes
В Yii2 MongoDB ActiveRecord нужно корректно описать атрибуты документа, с которыми работает модель
Путают массив моделей и массив полей
all() возвращает массив, но это может быть массив объектов. Проверяйте элемент, а не контейнер
Ждут модель от агрегированного результата
Если pipeline возвращает не обычный документ коллекции, ActiveRecord не сможет автоматически превратить его в полноценную модель. Для таких ответов используйте DTO или отдельную сборку данных
Что почитать дальше по MongoDB
Если нужен общий маршрут по теме, откройте рубрику MongoDB. Для соседних задач пригодятся эти разборы:
- Как сделать уникальный номер документа в MongoDB
- Discord bot на Python и MongoDB: как задать проверку
- Failed to start MongoDB database server: что проверить
- MongoDB Atlas: облачная база для первого проекта



