New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix query preparation when querying for referenced object #1481

Merged
merged 1 commit into from Aug 5, 2016

Conversation

Projects
None yet
2 participants
@alcaeus
Member

alcaeus commented Aug 1, 2016

This PR fixes an issue introduced with #1363 when running queries like $dm->getRepository(User::class)->findOneBy(['account' => $account]);, with $account being a referenced document. When using the references method of the query builder, the query array looks like this:

[
    'account.$id' => MongoId(...)
]

When using includesReferenceTo which is made for @ReferenceMany mappings, the result looks like this:

[
    'account' => [
        '$elemMatch' => [
            '$id' => MongoId(...)
        ]
    ]
]

However, the implementation in the DocumentPersister always yielded a full DBRef object:

[
    'account' => [
        '$ref' => 'accounts',
        '$id' => MongoId(...)
        '$db' => 'mydatabasename'
    ]
]

This caused issues when forcing queries to be covered by indexes (through the notablescan option in MongoDB), since it would require two different kinds of indexes on a reference: one on the entire DBRef object to cover queries like created through the DocumentPersister and another index on the $id field of the reference to cover queries created by the query builder in combination with references.

This solution tries to apply the same logic applied by the query builder to the documents in question. The only exception are @ReferenceOne fields without a target document set. These would produce the following query array:

[
    'account.$ref' => 'accounts',
    'account.$id' => MongoId(...),
    'account.$db' => 'mydatabasename'
]

This is not possible at this time since the DocumentPersister always assumes that a single field has exactly one value. For now, the PR includes a failing test case for this, as the DocumentPersister excludes @ReferenceOne fields without targetDocument set.

@alcaeus alcaeus added the bug label Aug 1, 2016

@alcaeus alcaeus added this to the 1.1.2 milestone Aug 1, 2016

@malarzm

This comment has been minimized.

Show comment
Hide comment
@malarzm

malarzm Aug 1, 2016

Member

As a starter I'm sorry for introducing the bug, I admit that I haven't thought about indexes at all back then :)

This is not possible at this time since the DocumentPersister always assumes that a single field has exactly one value.

If this is only issue of what's prepareQueryElement is returning (and how) it could be fairly easy (found 3 places using the method) to rework it so it could return an array of tuples (or ["field.$id" => abc, "field.$ref" => xyz] array) - what do you think?

Member

malarzm commented Aug 1, 2016

As a starter I'm sorry for introducing the bug, I admit that I haven't thought about indexes at all back then :)

This is not possible at this time since the DocumentPersister always assumes that a single field has exactly one value.

If this is only issue of what's prepareQueryElement is returning (and how) it could be fairly easy (found 3 places using the method) to rework it so it could return an array of tuples (or ["field.$id" => abc, "field.$ref" => xyz] array) - what do you think?

@alcaeus

This comment has been minimized.

Show comment
Hide comment
@alcaeus

alcaeus Aug 1, 2016

Member

it could be fairly easy to rework it so it could return an array of tuples

I thought about that as well - just wasn't sure which route we want to take. I'll have to see how we can accomodate that without creating a weird return type, but if at all possible I'll do exactly that. Thanks for the input! 👍

Member

alcaeus commented Aug 1, 2016

it could be fairly easy to rework it so it could return an array of tuples

I thought about that as well - just wasn't sure which route we want to take. I'll have to see how we can accomodate that without creating a weird return type, but if at all possible I'll do exactly that. Thanks for the input! 👍

@alcaeus

This comment has been minimized.

Show comment
Hide comment
@alcaeus

alcaeus Aug 2, 2016

Member

@malarzm udpated PR as per your suggestion. prepareQueryElement now returns an array of key-value tupels so that more than one query element can be returned.

Member

alcaeus commented Aug 2, 2016

@malarzm udpated PR as per your suggestion. prepareQueryElement now returns an array of key-value tupels so that more than one query element can be returned.

@malarzm

This comment has been minimized.

Show comment
Hide comment
@malarzm

malarzm Aug 5, 2016

Member

Thanks \o/

Member

malarzm commented Aug 5, 2016

Thanks \o/

@malarzm malarzm merged commit d3dddc0 into doctrine:1.1.x Aug 5, 2016

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@alcaeus alcaeus deleted the alcaeus:fix-dbref-queries branch Oct 4, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment