- DBRefs are objects whose first two fields must be $ref and $id (in that order). An optional $db field, if present, must appear third. Other fields may follow (they can't have a $ prefix, of course).
- $elemMatch should have consistent behavior, regardless of whether its argument or the value it is matching against look like DBRef objects.
The current implementation simply treats an $elemMatch on a DBRef as an equality match, which doesn't seem correct. Consider the following, which uses the latest nightly:
First, I create three documents in the test.people collection. The middle document has an extra field in its DBRef object, which is something Doctrine ODM has done for years to discriminate references to super-classes. Based on the DBRef docs, they're only objects that required $ref and $id as the first two fields with an optional $db to follow. There was never a restriction on additional fields, even though the shell likes to hide them (as it does $db).
The example below demonstrates the shortcoming of treating $elemMatch as an equality comparison, and relying on _isDBRefDocument() for the detection:
In the first and last example, we get the original error because $elemMatch doesn't recognize its argument as a DBRef and apply the patch logic. But even with the patch, the equality comparison fails to match anything in the middle two examples, since the DBRef in the database does have an extra _doctrine_class_name field within.
Repeating the test with the third example document, which doesn't include the extra Doctrine field:
We still have the same shortcomings, although the equality match in the last example does happen to work. I'm still not keen on that behavior because this is nothing like a real $elemMatch evaluation.