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
文档。
现在,我知道了“string
与 MongoId
”的问题 - 我们所有的 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 来解释问题,它已被标记为错误。所以这确实是一个错误的行为..
我有一个更大的项目,在 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
文档。
现在,我知道了“string
与 MongoId
”的问题 - 我们所有的 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 来解释问题,它已被标记为错误。所以这确实是一个错误的行为..