Skip to content

Doctrine\ODM\MongoDB\Persisters\CollectionPersister::deleteCollections don't remove all necessary elements #2195

Open
@TvitiDev

Description

@TvitiDev

Bug Report

Q A
BC Break no
Version 1.3.7

Summary

In upgrading version up to 1.3.* in DocumentPersister::handleCollections() method you made optimisation. Now you update the list collections in method CollectionPersister::updateAll() and method CollectionPersister::deleteCollections() remove all elements as one "$unset". But you lost the some paths for remove.

Current behavior and how to reproduce

For example, I have next document:

{
  "_id" : ObjectId("5ed602e89bfe8563bd61c302"),
  "property" : [
    {
      "value" : 100,
      "items" : [
        {
          "value" : 1,
          "is_flag" : false
        },
        {
          "value" : 2,
          "is_flag" : false
        },
        {
          "value" : 3,
          "is_flag" : false
        }
      ]
    },
    {
      "value" : 101,
      "items" : [
        {
          "value" : 1,
          "is_flag" : false
        },
        {
          "value" : 2,
          "is_flag" : false
        },
        {
          "value" : 3,
          "is_flag" : false
        }
      ]
    }
  ],
  "property_old" : [
    {
      "value" : 200,
      "items" : [
        {
          "value" : 1,
          "is_flag" : false
        },
        {
          "value" : 2,
          "is_flag" : false
        },
        {
          "value" : 3,
          "is_flag" : false
        }
      ]
    }
  ]
}

me need remove:

'property.1',
'property.0.items.2',
'property_old.0'

I expect, what your code remove this element, but your code remove only 'property.1', because variable $paths (line 368 of file CollectionPersister.php) contains next elements:
before execute method excludeSubPaths():

'property',
'property.0.items',
'property_old'

after execute method excludeSubPaths():

'property'

This is not correct. You lost 2 path for remove and will remove only 'property.1'

Expected behavior

I see 2 errors:

  1. Incorrect list paths before execute method excludeSubPaths(), he should contains:
'property.1',
'property.0.items.2',
'property_old.0'

but contains:

'property',
'property.0.items',
'property_old'
  1. If me need totally remove property "property" and remove "property_old.0" - method excludeSubPaths() return only path "property", because strpos('property_old.0', 'property') === 0 is true, but "property_old.0" not sub-path 'property'. Maybe need compare strpos($paths[$i], end($uniquePaths) . '.') === 0, because sub-path should have point?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions