0

I have the following data structure:

{ 
_id: 599cfc236ed0d81c98007f66
site: 'abc'
timepoints [
    { timepoint: 0
      testSites: [{testSite: 'abc', address: '123'},
                  {testSite: 'mno', address: '789'}],
    },
    { timepoint: 2
      testSites: [{testSite: 'abc', address: '123'}],
    },
    { timepoint: 4
      testSites: [{testSite: 'mno', address: '789'}],
    },
  ]
}

I have read through the MongoDB update operator for $pull, but it does not have an example of pulling a element from an array of an embedded/embedded document and I can't figure it out:

I would like to pull all elements whose site = 'abc' and whose testSite = 'abc', thus the result would be:

{ 
_id: 599cfc236ed0d81c98007f66
site: 'abc'
timepoints [
    { timepoint: 0
      testSites: [{testSite: 'mno', address: '789'}],
    },
    { timepoint: 2
      testSites: [],
    },
    { timepoint: 4
      testSites: [{testSite: 'mno', address: '789'}],
    },
  ]
}

I tried the following command, but it pulls all the timepoints documents and not the embedded documents within testSites:

$db->collection1->update(
         ['site' => 'abc'],
         ['$pull' => ['timepoints' => ['testSites' => ['$elemMatch' => ['testSite' => 'abc']]]]],
         ['multi' => true]);

UPDATE: I agree this is a duplicate question with an answer. I was just able to find the following:

MongoDB $pull array 2 level

So the command does pull the lower level element, but only from timepoint 0:

db.collection1.update({'site': 'abc', 
                       'timepoints.testSites.testSite': 'abc'},
                      {'$pull': {'timepoints.$.testSites': {'testSite': 'abc'}}},
                      {'multi': true}
                     );

Why is the second occurrence in timepoint 2 not pulled?

Chris Wolcott
  • 302
  • 1
  • 3
  • 9
  • 1
    `->update([ 'site' => 'abc' , 'timepoints.timepoint' => 0 ],[ '$pull' => [ 'timepoints.$.testsites' => [ 'testSite' => 'abc' ] ] ])`. That's the general correction as pointed out ( not actually in the accepted answer ) in the responses to the linked duplicate. Also note that it is not possibly at this present time to update "multiple array elements" in a single request. ( other linked duplicate ) – Neil Lunn Sep 18 '17 at 12:23
  • Thank you, you just answered my question to "multiple array elements" in a single request. So what is my best option to pull all testSite = 'abc' from timepoints. – Chris Wolcott Sep 18 '17 at 12:29
  • 1
    I actually answered both questions when you look carefully. – Neil Lunn Sep 18 '17 at 12:30
  • Thanks, instead of a single request I went ahead and built a cursor and iterated over each timepoint and if it had assaySites I iterated over each assaySite. If it matched my requirement I unset the index and check if the assaySites was emtpy and unset the assaySites array. – Chris Wolcott Sep 18 '17 at 19:45

0 Answers0