|
| 1 | +[[mongodb.repositories.queries]] |
| 2 | += MongoDB-specific Data Manipulation Methods |
| 3 | + |
| 4 | +Next to the xref:mongodb/repositories/query-methods.adoc[query methods] it is possible to update data with specialized methods. |
| 5 | + |
| 6 | +[[mongodb.repositories.queries.update]] |
| 7 | +== Update Methods |
| 8 | + |
| 9 | +You can also use the keywords in the preceding table to create queries that identify matching documents for running updates on them. |
| 10 | +The actual update action is defined by the `@Update` annotation on the method itself, as the following listing shows. |
| 11 | +Note that the naming schema for derived queries starts with `find`. |
| 12 | +Using `update` (as in `updateAllByLastname(...)`) is allowed only in combination with `@Query`. |
| 13 | + |
| 14 | +The update is applied to *all* matching documents and it is *not* possible to limit the scope by passing in a `Page` or by using any of the <<repositories.limit-query-result,limiting keywords>>. |
| 15 | +The return type can be either `void` or a _numeric_ type, such as `long`, to hold the number of modified documents. |
| 16 | + |
| 17 | +.Update Methods |
| 18 | +==== |
| 19 | +[source,java] |
| 20 | +---- |
| 21 | +public interface PersonRepository extends CrudRepository<Person, String> { |
| 22 | +
|
| 23 | + @Update("{ '$inc' : { 'visits' : 1 } }") |
| 24 | + long findAndIncrementVisitsByLastname(String lastname); <1> |
| 25 | +
|
| 26 | + @Update("{ '$inc' : { 'visits' : ?1 } }") |
| 27 | + void findAndIncrementVisitsByLastname(String lastname, int increment); <2> |
| 28 | +
|
| 29 | + @Update("{ '$inc' : { 'visits' : ?#{[1]} } }") |
| 30 | + long findAndIncrementVisitsUsingSpELByLastname(String lastname, int increment); <3> |
| 31 | +
|
| 32 | + @Update(pipeline = {"{ '$set' : { 'visits' : { '$add' : [ '$visits', ?1 ] } } }"}) |
| 33 | + void findAndIncrementVisitsViaPipelineByLastname(String lastname, int increment); <4> |
| 34 | +
|
| 35 | + @Update("{ '$push' : { 'shippingAddresses' : ?1 } }") |
| 36 | + long findAndPushShippingAddressByEmail(String email, Address address); <5> |
| 37 | +
|
| 38 | + @Query("{ 'lastname' : ?0 }") |
| 39 | + @Update("{ '$inc' : { 'visits' : ?1 } }") |
| 40 | + void updateAllByLastname(String lastname, int increment); <6> |
| 41 | +} |
| 42 | +---- |
| 43 | +
|
| 44 | +<1> The filter query for the update is derived from the method name. |
| 45 | +The update is "`as is`" and does not bind any parameters. |
| 46 | +<2> The actual increment value is defined by the `increment` method argument that is bound to the `?1` placeholder. |
| 47 | +<3> Use the Spring Expression Language (SpEL) for parameter binding. |
| 48 | +<4> Use the `pipeline` attribute to issue xref:mongodb/template-crud-operations.adoc#mongo-template.aggregation-update[aggregation pipeline updates]. |
| 49 | +<5> The update may contain complex objects. |
| 50 | +<6> Combine a xref:mongodb/repositories/repositories.adoc#mongodb.repositories.queries.json-based[string based query] with an update. |
| 51 | +==== |
| 52 | + |
| 53 | +WARNING: Repository updates do not emit persistence nor mapping lifecycle events. |
| 54 | + |
| 55 | +[[mongodb.repositories.queries.delete]] |
| 56 | +== Delete Methods |
| 57 | + |
| 58 | +The keywords in the preceding table can be used in conjunction with `delete…By` or `remove…By` to create queries that delete matching documents. |
| 59 | + |
| 60 | +.`Delete…By` Query |
| 61 | +[tabs] |
| 62 | +====== |
| 63 | +Imperative:: |
| 64 | ++ |
| 65 | +[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
| 66 | +---- |
| 67 | +public interface PersonRepository extends MongoRepository<Person, String> { |
| 68 | +
|
| 69 | + List <Person> deleteByLastname(String lastname); <1> |
| 70 | +
|
| 71 | + Long deletePersonByLastname(String lastname); <2> |
| 72 | +
|
| 73 | + @Nullable |
| 74 | + Person deleteSingleByLastname(String lastname); <3> |
| 75 | +
|
| 76 | + Optional<Person> deleteByBirthdate(Date birthdate); <4> |
| 77 | +} |
| 78 | +---- |
| 79 | +<1> Using a return type of `List` retrieves and returns all matching documents before actually deleting them. |
| 80 | +<2> A numeric return type directly removes the matching documents, returning the total number of documents removed. |
| 81 | +<3> A single domain type result retrieves and removes the first matching document. |
| 82 | +<4> Same as in 3 but wrapped in an `Optional` type. |
| 83 | +
|
| 84 | +Reactive:: |
| 85 | ++ |
| 86 | +[source,java,indent=0,subs="verbatim,quotes",role="secondary"] |
| 87 | +---- |
| 88 | +public interface PersonRepository extends ReactiveMongoRepository<Person, String> { |
| 89 | +
|
| 90 | + Flux<Person> deleteByLastname(String lastname); <1> |
| 91 | +
|
| 92 | + Mono<Long> deletePersonByLastname(String lastname); <2> |
| 93 | +
|
| 94 | + Mono<Person> deleteSingleByLastname(String lastname); <3> |
| 95 | +} |
| 96 | +---- |
| 97 | +<1> Using a return type of `Flux` retrieves and returns all matching documents before actually deleting them. |
| 98 | +<2> A numeric return type directly removes the matching documents, returning the total number of documents removed. |
| 99 | +<3> A single domain type result retrieves and removes the first matching document. |
| 100 | +====== |
0 commit comments