我有一个更大的项目,在symfony环境下使用doctore2odm。
给定一个简单的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>
我想使用
App
字段上的MongoRegex
表达式查询_id
文档。现在,我知道了“
string
对MongoId
”的问题-我们所有的id都是正确的字符串。当我试图通过mongodb shell(使用robomongo作为gui)执行此操作时,一切都很好,因为此表达式成功地返回了我正在搜索的对象:
App.find({'_id': /^ad.*$/i})
但在php上下文中它是不同的。条令2 ODM中有一种特殊的逻辑,它处理对标识符字段的
equals()
搜索,这与普通的equals
不同。质疑一个正常的领域条令2 ODM行为
我们的
name
实体中有正常场App
。如果我们想对此进行类似的搜索,我们会这样做(假设$builder
是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
),它将被转换为一个数组,并且该值将被替换为返回数据类型(在本例中为getDatabaseIdentifierValue()
)的ClassMetaDataInfo
而不是string
实例。我的问题
所以我们知道它是如何发生的,但不知道为什么-在标识符字段上的
MongoRegex
操作中进行这种转换的原因是什么?有必要这么做吗?如何使用Doctrine 2 ODM在标识符字段上使用regex进行查询?我们知道它在MongoDB外壳中工作,为什么不在这里呢?
我先把这个问题作为一个so问题发布,而不是document2odm问题,因为这仍然是一个问题。如果没有人知道这样做的原因,我将尝试为odm维护人员提出github问题。
最佳答案
创建这个之后,我创建了一个Github issue来解释这个问题,它被标记为一个bug。所以这确实是一种错误的行为。
关于php - Doctrine 2 ODM:使用LIKE查询带有MongoRegex的ID字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34061566/