MongoDB 按引用字段过滤 (ORM)

MongoDB filter by reference's field (ORM)

假设我有文档 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,然后您可以使用它来查询城市集合:

{ "country": ObjectId(...) }

如果出于某种原因,您想通过某个国家/地区的非唯一值(例如大陆、名称的子字符串匹配)来查找城市,这仍然可以在两个查询中完成。第一个将再次为符合条件的任何国家/地区找到 ObjectId。然后,第二个查询将使用 $in 运算符和一个 ObjectIds 数组:

{ "country": { "$in": [ ObjectId(...), ObjectId(...), ... ]}}

如果您使用 Doctrine MongoDB ODM, the query builder supports this via the references() and includesReferenceTo() methods in Expr.php (also exposed through Builder.php). references() and includesReferenceTo() can be used to match on a single document reference existing in a ReferenceOne or ReferenceMany relationship, respectively. They also correctly handle simple (i.e. just ObjectId) and complex (i.e. DBRef) 参考文献。

也就是说,ODM 查询生成器 没有 匹配多个引用的方法(请注意,上述两种方法都采用单个文档参数)。由于您使用的是简单引用,因此使用 in() 应该很容易做到这一点,正如我在第二段中提到的那样;然而,如果我们使用 DBRefs 查询会更复杂(我们需要混合 $elemMatch$in,正如在 ODM 项目 this answer). I've opened issue #1024 中讨论的那样以跟踪此功能请求.

对于 @MongoDB\ReferenceOne[,您必须使用查询生成器的 references() 方法=26=]喜欢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:使用includesReferenceTo()一个@MongoDB\ReferenceMany