Doctrine 2 ODM:使用带有 LIKE 的 MongoRegex 查询 ID 字段

Doctrine 2 ODM: Querying ID field with MongoRegex with LIKE

我有一个更大的项目,在 Symfony 上下文中使用 Doctrine 2 ODM。

给定一个简单的 ODM 实体(XML 定义):

<document name="\Document\App" repository-class="\Repository\AppRepository">
  <field fieldName="id" type="string" id="true" strategy="UUID"/>
  <field fieldName="name" type="string"/>
</document>

我想在 _id 字段上使用 MongoRegex 表达式查询 App 文档。

现在,我知道了“stringMongoId”的问题 - 我们所有的 ID 都是正确的字符串。

当我尝试通过 MongoDB shell 执行此操作时(使用 Robomongo 作为 GUI);没关系,因为这个表达式成功 returns 我正在搜索的对象:

App.find({'_id': /^ad.*$/i})

但在 PHP 上下文中是不同的。在 Doctrine 2 ODM 中有特殊的逻辑处理 equals() 与正常 equals 不同的标识符字段搜索。

查询普通字段 Doctrine 2 ODM 行为

我们的 App 实体中有普通字段 name。如果我们想对其进行类似搜索,我们会这样做(假设 $builder 是 instanceof QueryBuilder

$builder->field("name")->equals(new \MongoRegex("/^ad.*$/i"));

如果我们随后检查 QueryBuilder 调用了 $builder->getQueryArray(),我们会看到:

array (size=1)
 'name' => 
    object(MongoRegex)[628]
    public 'regex' => string '^ad.*$' (length=6)
    public 'flags' => string 'i' (length=1)

这很好,而且很有效。我们有我们的 MongoRegex 实例在那里..

使用 MongoRegex Doctrine 2 ODM 行为查询 _id 字段

标识符字段完全不同。

让我们这样做:

$builder->field("id")->equals(new \MongoRegex("/^ad.*$/i"));

现在让我们再次检查 $builder->getQueryArray():

array (size=1)
  '_id' => string '/^ad.*$/i' (length=9)

嗯,查询中没有 MongoRegex 个实例。事实上,查询不起作用..

查找原因

这个问题不是这是怎么发生的。我知道怎么做 - 但不知道 为什么 ..让我们看看 Doctrine 2 ODM 代码。

此转换发生在 Doctrine\ODM\MongoDB\Persisters\DocumentPersister (see code here)。

摘录:

// Process identifier fields
    if (($class->hasField($fieldName) && $class->isIdentifier($fieldName)) || $fieldName === '_id') {
        $fieldName = '_id';
        if ( ! $prepareValue) {
            return array($fieldName, $value);
        }
        if ( ! is_array($value)) {
            return array($fieldName, $class->getDatabaseIdentifierValue($value));
        }

如果查询值不是数组(不是什么,是MongoRegex),它会被转换为1,并且该值会被return替换数据类型的 ClassMetaDataInfo (see call here) 的 35=](在本例中为 string)——这将是一个普通字符串而不是 MongoRegex 实例。

我的问题

所以我们知道 如何 它发生但不知道 为什么 - 在 equals() 操作中进行此转换的原因是什么标识符字段?有必要这样做吗?

如何使用 Doctrine 2 ODM 在标识符字段上使用正则表达式进行查询?我们知道它在 MongoDB shell 中有效,为什么在这里不行?

我首先将其作为 SO 问题而不是 Doctrine 2 ODM 问题发布,因为这仍然是一个问题。如果没有人知道这样做的原因,我会尝试向 ODM 维护者提出 Github 问题。

创建这个之后,我创建了一个 Github issue 来解释问题,它已被标记为错误。所以这确实是一个错误的行为..