2

I have a collection of documents like this in a mongo db :

"_id" : ObjectId("592bc37c339e7a23788b4c7c"),
"trips" : [ 
    {
        "tripGcsId" : "5937f86e339e7a2a58ac3186",
        "tripCounter" : NumberLong(1283),
        "tripRef" : "hjkhjk"
    }, 
    {
        "tripGcsId" : "5937f914339e7a2a58ac318b",
        "tripCounter" : NumberLong(1284),
        "tripRef" : "fjh"
    }
]

and a method on the server side (Spring+Mongo):

public List<String> removeTripObject( List<String> tripIds )
{
    Query query = Query.query( Criteria.where( "trips" ).elemMatch( Criteria.where( "tripGcsId" ).in( tripIds ) ) );

    Update update = new Update().pullAll( "trips.tripGcsId", new Object[] { tripIds } );
    getMongoTemplate().updateMulti( query, update, "ORDER" );
    return updatedOrders;
}

The parameter tripIds is a list of tripGcsIds to be removed from trips array. The method above gives me the error: Write failed with error code 16837 and error message 'cannot use the part (trips of trips.tripGcsId) to traverse the element.

When I try with the $ operator, as described in other SO answers like this:

public List<String> removeTripObject( List<String> tripIds )
{
    Query query = Query.query( Criteria.where( "trips" ).elemMatch( Criteria.where( "tripGcsId" ).in( tripIds ) ) );

    Update update = new Update().pullAll( "trips.$.tripGcsId", new Object[] { tripIds } );
    getMongoTemplate().updateMulti( query, update, "ORDER" );
    return updatedOrders;
}

i got this error: Write failed with error code 16837 and error message 'Can only apply $pullAll to an array.

I'm not sure how should this pullAll command look like on the server side.

s7vr
  • 73,656
  • 11
  • 106
  • 127
neptune
  • 1,211
  • 2
  • 19
  • 32
  • As the error message says, you can do pull on an array. You are trying to do pull on `trips.tripGcsId` which is not an array. `trips` is an array – pvpkiran Jun 07 '17 at 13:18

1 Answers1

3

You need to use $pull update operator which takes the query to match and delete all the matching rows in embedded array.

Something like

public List<String> removeTripObject( List<String> tripIds ) {
    Query query = Query.query( Criteria.where( "tripGcsId" ).in( tripIds ) );
    Update update = new Update().pull("trips", query );
    getMongoTemplate().updateMulti( new Query(), update, "ORDER" );
    return updatedOrders;
}

Reference

https://docs.mongodb.com/manual/reference/operator/update/pull/#remove-items-from-an-array-of-documents

s7vr
  • 73,656
  • 11
  • 106
  • 127