Manuelarte
Manuelarte

Reputation: 1810

Increase value of a field inside an array of element

I have documents that has the following structure in my collection:

{
    "_id": "1234566780",
    "arrayField": [
      {
        "id": "1",
        "count": 3
      },
      {
        "id": "2",
        "count": 5
      }
    ]
}

I want to have a method in my CollectionRepository that increments the value of the field count by giving to the method the collection id and the field id of the elements in the arrayField.

I have the feeling that it is not possible to do it with Spring Data autogenerated queries by method names.

So I'm trying to do it with the @Query annotation, but I have no idea on how to do it, since I need to select the collection based on _id, then select the field inside the array based on id, and then increase the count by one. Any hints?

Upvotes: 1

Views: 54

Answers (1)

charlycou
charlycou

Reputation: 1988

Sorry for the delay, here is a solution to your problem.

You can update a specific element of an array using arrayFilter update option. The MongoDB update operation would look like:

db.collection.update(
    {"_id":"1234566780"},
    {$inc:{"arrayField.$[elem].count":1}},
    {arrayFilters:[{"elem.id":"2"}]}

Admiting you are using MongoDB server and MongoDB java Driver version 3.6 or greater you could use:

public void updateCollection () {
    MongoCollection<Document> collection = mongoTemplate.getDb().getCollection("collection");
    Bson query = new Document("_id", "1234566780");
    Bson update = Updates.inc("arrayField.$[elem].count",1);
    UpdateOptions updateOptions = new UpdateOptions().arrayFilters(Arrays.asList( Filters.eq("elem.id","2")));
    collection.updateOne(query, update, updateOptions);
}

Indeed Spring data method signature is not likely to generate this update. What I suggest you is to extend a CustomCollectionRepository interface with your CollectionRepository. You could define this update method signature in this interface and implement it in a CustomCollectionRepositoryImpl class. Please find the part of the documentation that mention this solution.

Upvotes: 1

Related Questions