1

Here's my data structure:

db.getCollection('competitionmatches').find()
{
    "_id" : ObjectId("5d2d9eed5972a9367cd5010a"),
    "matches" : [ 
        {
            "id" : 200000,
            "utcDate" : "",
            "minute" : null,
            "homeTeam" : {
                "id" : 808,
                "coach" : {},
            },
            "goals" : [{},{}}],
        },
        {...},
        {...},
    ],
    "otherField": []
},
{...},
{...},

What i'm trying to remove are those fields: minute, coach and goals in all matches of all entries in competitionmatches.

I've tried the following in Robo 3T with success:

db.getCollection('competitionmatches').update({}, {$unset: {"otherField":""}})

This removes well the whole array otherField in each element of matches if i pass multi:true (removed here for the sake of readability).

But when i try:

db.getCollection('competitionmatches').update({}, {$unset: {"matches.$[].goals":""}})

or

db.getCollection('competitionmatches').update({}, {$unset: {"matches.$[].minute":""}})

i get a success message Updated 1 existing record(s) in 3ms but the record stay the same, minute or goals do not get removed.

I got this answer from Remove a field from all elements in array in mongodb and updated my mongo version from 3.4 to 3.6 because the $[] was introduced in 3.6 as said by svr and shown in the docs.

Unset works but the path seems to be the wrong part of my update.

"matches.$.goals" returns an error and matches.[].goals does not have any impact as well. I was even wondering if there could be some cache but that does not make much sense since the unset on otherField gets executed well.

I was also in doubt if the update went well but the app using the database works fine as far as i can see.

1 Answer 1

2

The update can't access direct array field using $ or $[], we need to provide query to match in array,

db.getCollection('competitionmatches').update(
  // it requires to specify any one field match condition in query part
  { "matches.goals": { $exists: true } }, 
  { 
    $unset: { 
      "matches.$[].minute": true // pass true
      "matches.$[].homeTeam.coach": true // pass true
      "matches.$[].goals": true // pass true
    } 
  } 
);

Mongo shell

> db.upd22.find()
[
  {
    _id: ObjectId("5d2d9eed5972a9367cd5010a"),
    matches: [
      {
        id: 200000,
        utcDate: '',
        minute: null,
        homeTeam: { id: 808, coach: {} },
        goals: [ {}, {} ]
      },
      {
        id: 300000,
        utcDate: '',
        minute: null,
        homeTeam: { id: 808, coach: {} },
        goals: [ {}, {} ]
      }
    ]
  },
  {
    _id: ObjectId("5d2d9eed5972a9367cd5010b"),
    matches: [
      {
        id: 400000,
        utcDate: '',
        minute: null,
        homeTeam: { id: 808, coach: {} },
        goals: [ {}, {} ]
      },
      {
        id: 500000,
        utcDate: '',
>                                                                                                                                          homeTeam: { id: 808, coach: {} },
        goals: [ {}, {} ]
      }
    ]
  }
]
> db.getCollection('upd22').update(
...     { "matches.goals": { $exists: true } },
...     {
.....         $unset: {
.......             "matches.$[].minute": true,
.......             "matches.$[].goals": true
.......         }
.....     },
...     { multi: false }
... )
{
  acknowledged: 1,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}
> db.upd22.find()
[
  {
    _id: ObjectId("5d2d9eed5972a9367cd5010a"),
    matches: [
      { id: 200000, utcDate: '', homeTeam: { id: 808, coach: {} } },
      { id: 300000, utcDate: '', homeTeam: { id: 808, coach: {} } }
    ]
  },
  {
    _id: ObjectId("5d2d9eed5972a9367cd5010b"),
    matches: [
      {
        id: 400000,
        utcDate: '',
        minute: null,
        homeTeam: { id: 808, coach: {} },
        goals: [ {}, {} ]
      },
      {
        id: 500000,
        utcDate: '',
        minute: null,
        homeTeam: { id: 808, coach: {} },
        goals: [ {}, {} ]
      }
    ]
  }
]
>

Sign up to request clarification or add additional context in comments.

6 Comments

Just tried but no luck. I used the following:db.getCollection('competitionmatches').update({ "matches.goals": { $exists: true } }, { $unset: { "matches.$[].minute": true, "matches.$[].goals": true}} , { multi:false }) Note, coach is within the homeTeam object.
its removing both fields from first document, that is not working your side?
i get an "Updated 1 existing record(s)" as the result but when refreshing the data with a new find() i can still see bopth fields in at least the first two entries of the array matches.
I've narrowed the query to a specific competitionMatches by id with db.getCollection('competitionmatches').update({ "_id": ObjectId("5d2d9eed5972a9367cd5010a"), "matches.goals": { $exists: true } }, { $unset: { "matches.$[].minute": true, "matches.$[].goals": true}} , { multi:false })
Just did a quick test by adding at the root of the competitionMatches with the id above a field temporary and removing it with db.getCollection('competitionmatches').update({ "_id": ObjectId("5d2d9eed5972a9367cd5010a"), "matches.goals": { $exists: true } }, { $unset: { "tempo":true, "matches.$[].minute": true, "matches.$[].goals": true}} , { multi:false }) and it worked. So i guess the problem os really entering the array and finding the desired fields.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.