我有一个这样的文档:
[_id] => MongoId Object (
[$id] => 542e6f6f10f0ed75138b4567
)
[description] => Lorem...
[lat] => 37.5184124
[lng] => 15.015836000000036
[name] => My company
[phone] => +4977665556
[photos] => Array (
[0] => Array (
[_id] => MongoId Object (
[$id] => 542e6f7a10f0ed73138b4567
)
[image] => 06c2aeb0a8fbc03b7c77732166114a23.jpg
)
[1] => Array (
[_id] => MongoId Object (
[$id] => 542e6f7c10f0ed77138b4568
)
[image] => a7a428c48291137bade2fd81c842c5ab.jpg
)
)
现在我只想得到一个带有ODM原则的数组photos
。
我尝试了这个查询,但不起作用:
$this->createQueryBuilder('Company')
->select('photos')
->field('ID')->equals($id)
->getQuery()
->getSingleResult();
此查询不仅返回photos
,还返回所有文档。
为什么
使用Builder::select()
投影特定字段并不意味着查询将单独返回该字段。公司的查询生成器将始终返回公司对象。在您的案例中,getSingleResult()
让查询返回单个对象,而不是Company对象的可迭代游标。select()
投影意味着MongoDB查询将只返回_id
和photos
字段,然后这些字段将被水合为Company对象。
因此,您会发现Company::getName()
可能返回null
,而Company::getPhotos()
可能返回Photo对象的PersistentCollection
。从您的示例中,我不清楚这些文档是被引用的还是只是嵌入了带有_id
字段的文档。
默认情况下,ODM水合物查询结果。当您使用投影来排除字段时,这可能会产生问题,因为对未水合字段的任何进一步分配都可能被视为更改并持久化回数据库。如果你想获得原始数据,你可以通过Builder::hydrate()
禁用水合作用,这需要一个布尔值。
附带说明一下,我建议您在field()
查询中使用'id'
或'_id'
,而不是'ID'
。我不确定ODM在查找映射字段时是否会进行不区分大小写的字符串比较——当然,除非您的PHP属性是$ID
,在这种情况下,您可以忽略此建议。