假设我有文档city
和文档country
。
city
"引用country: ObjectId("xxxx")
country
如何按国家/地区的字段查找城市,例如。 db.Cities.find({"country.code":"US"}
可能吗?我认为不是,但是可以使用MongoDB ORM进行PHP吗?
我试过了
$qb = $this->database->createQueryBuilder(self::NAMESPACE_CITY);
$qb->field('country.code')->equals("US")`
我的City
实体包含
/** @ODM'ReferenceOne(targetDocument="'Doctrine'Documents'Country", simple=true) */
protected $country;
文档示例:
<?php
namespace Doctrine'Documents;
use Doctrine'ODM'MongoDB'Mapping'Annotations as ODM;
use Application'Doctrine'Documents'Document;
/** @ODM'Document(collection="Cities") */
class City extends Document {
/** @ODM'Id */
protected $_id;
/** @ODM'ReferenceOne(targetDocument="'Doctrine'Documents'Country", simple=true) */
protected $country;
}
在单个查询中按国家/地区代码查询城市文档需要联接两个集合,这不受支持。您可以通过首先使用给定代码查找国家/地区(我假设这是一个唯一的字符串)将其分为两个查询。该查询将生成国家/地区的 ObjectId,然后您可以使用该 ObjectId 来查询城市集合:
{ "country": ObjectId(...) }
如果出于某种原因,您想通过国家/地区的一些非唯一值(例如大陆、名称上的子字符串匹配)来查找城市,这仍然可以在两个查询中完成。第一个将再次找到符合标准的任何国家的 ObjectId。然后,第二个查询将使用带有 ObjectId 数组的 $in
运算符:
{ "country": { "$in": [ ObjectId(...), ObjectId(...), ... ]}}
如果您使用的是 Doctrine MongoDB ODM,查询生成器将通过 Expr.php
中的 references()
和 includesReferenceTo()
方法(也通过 Builder.php
公开)支持此功能。 references()
和 includesReferenceTo()
可用于分别匹配 ReferenceOne 或 ReferenceMany 关系中存在的单个文档引用。它们还可以正确处理简单(即只是 ObjectId)和复杂(即 DBRef)引用。
也就是说,ODM 查询生成器没有与多个引用匹配的方法(请注意,上述两种方法都采用单个文档参数)。由于您使用的是简单的引用,因此使用 in()
应该很容易做到这一点,正如我在第二段中提到的;但是,如果我们使用 DBRefs,查询会更复杂(我们需要混合$elemMatch
和$in
,如本答案所述)。我已经在 ODM 项目上打开了问题 #1024 以跟踪此功能请求。
您必须使用 Query Builder 的 references() 方法来实现 @MongoDB''ReferenceOne 像 https://doctrine-mongodb-odm.readthedocs.org/en/latest/reference/query-builder-api.html
$country = $dm->getRepository('Country')->findOneByCode('US');
$queryBuilder = $dm->getRepository('City')->createQueryBuilder()
->field('country')->references($country);
$citiesByCountry = $queryBuilder->getQuery()->execute();
PS: use includeReferenceTo() a @MongoDB''ReferenceMany