diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc index 71a9554f764..6555fba4f24 100644 --- a/docs/modules/ROOT/nav.adoc +++ b/docs/modules/ROOT/nav.adoc @@ -1,6 +1,7 @@ * xref:index.adoc[Getting Started] -** xref:migrating.adoc[Migrating] ** xref:quicktour.adoc[Quick Tour] +** xref:migrating.adoc[Migrating] +*** xref:updating-old.adoc[Legacy Update API (pre-3.0)] * Features ** xref:configuration.adoc[Configuration] @@ -13,11 +14,11 @@ ** xref:updates.adoc[Updating] ** xref:deletes.adoc[Deleting] ** xref:aggregations.adoc[Aggregation] -** xref:textSearches.adoc[Text Search] +** xref:text-searches.adoc[Text Search] ** xref:references.adoc[References] ** xref:transactions.adoc[Transactions] -** xref:lifeCycleMethods.adoc[Life Cycle Methods] -** xref:schemaValidation.adoc[Schema Validation] +** xref:life-cycle-methods.adoc[Life Cycle Methods] +** xref:schema-validation.adoc[Schema Validation] * _Support_ ** xref:issues-help.adoc[Issues & Support] diff --git a/docs/modules/ROOT/pages/aggregation-expressions.adoc b/docs/modules/ROOT/pages/aggregation-expressions.adoc index dac2bce1bdc..e71faa6b87c 100644 --- a/docs/modules/ROOT/pages/aggregation-expressions.adoc +++ b/docs/modules/ROOT/pages/aggregation-expressions.adoc @@ -1,3 +1,5 @@ +:page-partial: + [%header,cols="1,2,3"] |=== |Operator|Docs|Test Examples diff --git a/docs/modules/ROOT/pages/aggregation-stages.adoc b/docs/modules/ROOT/pages/aggregation-stages.adoc index d8dcf580168..0b7e854512e 100644 --- a/docs/modules/ROOT/pages/aggregation-stages.adoc +++ b/docs/modules/ROOT/pages/aggregation-stages.adoc @@ -1,3 +1,5 @@ +:page-partial: + [%header,cols="1,2,3"] |=== |Operator|Docs|Test Examples diff --git a/docs/modules/ROOT/pages/aggregations.adoc b/docs/modules/ROOT/pages/aggregations.adoc index a24ef907aa4..43e59c02cd0 100644 --- a/docs/modules/ROOT/pages/aggregations.adoc +++ b/docs/modules/ROOT/pages/aggregations.adoc @@ -1,11 +1,11 @@ -== Aggregations += Aggregations The {docsRef}/aggregation[aggregation framework] in MongoDB allows you to define a series (called a pipeline) of operations (called stages) against the data in a collection. These pipelines can be used for analytics or they can be used to convert your data from one form to another. This guide will not go in to the details of how aggregation works, however. The official MongoDB {docsRef}/aggregation[documentation] has extensive tutorials on such details. Rather, this guide will focus on the Morphia API. The examples shown here are taken from the -{srcRef}/morphia/src/test/java/dev/morphia/aggregation/AggregationTest.java[tests] in Morphia itself. You can find the full list in the <> section. +{srcRef}/core/src/test/java/dev/morphia/aggregation/AggregationTest.java[tests] in Morphia itself. You can find the full list in the <> section. Writing an aggregation pipeline starts just like writing a standard query. As with querying, we start with the `Datastore`: @@ -17,7 +17,7 @@ include::example$TestDocsExamples.java[tag=basic] `aggregate()` takes a `Class` literal. This lets Morphia know which collection to perform this aggregation against. Because of the transformational operations available in the aggregation {docsRef}/core/aggregation-pipeline[pipeline], Morphia can not validate as much as it can with querying so care will need to be taken to ensure document fields actually exist when referencing them in your pipeline. -=== The Pipeline +== The Pipeline Aggregation pipelines are comprised of a series stages. Our example here with the `group()` stage. This method is the Morphia equivalent of the @@ -34,7 +34,7 @@ the Morphia equivalent of an {docsRef}/reference/operator/aggregation/group/#gro { "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] } ---- -=== Executing the Pipeline +== Executing the Pipeline Once your pipeline is complete, you can execute it via the `execute()` method. This method optionally takes a `Class` reference for the target type of your aggregation. @@ -43,7 +43,7 @@ Additionally, you can also include some options to `execute()`. We can use the various options on the link:javadoc/dev/morphia/aggregation/AggregationOptions.html[AggregationOptions] class to configure how we want the pipeline to execute. -==== $out +== $out Depending your use case, you might not want to return the results of your aggregation but simply output them to another collection. That's where `$out` comes in. {docsRef}/reference/operator/aggregation/out/[$out] is an operator that allows the results of a pipeline to be stored in to a named collection. @@ -66,7 +66,7 @@ that reflects the collection we want to write our output to. Morphia will use t your entities to determine that collection name. You may also pass a String with the collection name as well if the target collection does not correspond to a mapped entity. -==== $merge +== $merge {docsRef}/reference/operator/aggregation/merge/[$merge] is a very similar option with a some major differences. The biggest difference is that `$merge` can write to existing collections without destroying the existing documents. `$out` would @@ -86,7 +86,7 @@ Because there may be existing data in the collection, we need to instruct the op In this example, when documents matching we're choosing to replace them and when they don't we're instructing the operation to insert the new documents in to the collection. Other options are defined on `com.mongodb.client.model.MergeOptions` type defined by the Java driver. -=== Supported Operators +== Supported Operators Every effort is made to provide 100% coverage of all the operators offered by MongoDB. A select handful of operators have been excluded for reasons of suitability in Morphia. In short, some operators just don't make sense in Morphia. Below is listed all the currently supported operators. To see an example of an operator in action, click through to see the test cases for that operator. diff --git a/docs/modules/ROOT/pages/configuration.adoc b/docs/modules/ROOT/pages/configuration.adoc index 5d6cae228ab..92503caaa1c 100644 --- a/docs/modules/ROOT/pages/configuration.adoc +++ b/docs/modules/ROOT/pages/configuration.adoc @@ -1,28 +1,28 @@ -== Configuration += Configuration -Starting in Morphia 3.0, configuration will be driven via a configuration file. However programmatic configuration is still supportedfor those who prefer, or need, a more flexible approach. The file should live in your build's resources folder and be named `META-INF/morphia-config.properties`. Reference documentation for the configuration file can be found in the link:++javadoc/dev/morphia/config/MorphiaConfig.html++[javadoc] but +Starting in Morphia 3.0, configuration will be driven via a configuration file. However programmatic configuration is still supported for those who prefer, or need, a more flexible approach. The file should live in your build's resources folder and be named `META-INF/morphia-config.properties`. Reference documentation for the configuration file can be found in the link:++javadoc/dev/morphia/config/MorphiaConfig.html++[javadoc] but we'll go in depth on a few items here. An example configuration file is included below. All possible configuration elements are listed. However, if the default values are acceptable that element can be safely omitted from your file. `Morphia.createDatastore()` can be called link:++javadoc/dev/morphia/Morphia.html#createDatastore(com.mongodb.client.MongoClient,dev.morphia.config.MorphiaConfig)++[with] and link:++javadoc/dev/morphia/Morphia.html#createDatastore(com.mongodb.client.MongoClient)++[without] an explicit `MorphiaConfig` -argument. When not explicitly given a `MorphiaConfig`, Morphia will attempt to load the configuration file at the location show above. +argument. When not explicitly given a `MorphiaConfig`, Morphia will attempt to load the configuration file at the location shown above. Failing to find a configuration file, it will create a new configuration using the default values which can be found in the javadoc. These values are unlikely to be suitable long term but should be sufficient for newcomers looking to test things out a little before committing to adopt Morphia. -=== Manually loading configurations +== Manually loading configurations In some cases, you might find the need for multiple configuration files. Such scenarios include varying test environments/configurations, multiple dataset configurations, or externally supplied configurations. In such cases, you can manually load those configurations using link:++javadoc/dev/morphia/config/MorphiaConfig.html#load(java.lang.String)++[MorphiaConfig.load()]. You can then pass this instance to `createDatastore()`. -=== Dynamic configuration creation +== Dynamic configuration creation For many, the ability to dynamically create `MorphiaConfig` instances is not just a nicety but a hard requirement. In this case, there are methods on `MorphiaConfig` to return a new version of the configuration with the updated value. `MorphiaConfig` is immutable, however, so be sure to use the returned reference and not the original. It should also be noted that once a `Datastore` is created using a `MorphiaConfig`, that configuration is fixed and can not be changed. A new `Datastore` would need to be created with the updated version. -=== Collection and property naming +== Collection and property naming * `morphia.collection-naming` * `morphia.property-naming` @@ -50,7 +50,7 @@ For the provided strategies, you can simply use the shortened version as shown i can enable it by giving the fully qualified classname (fqcn) instead. The same applies everywhere you see `fqcn` in the sample file. ==== -=== Discriminator keys and values +== Discriminator keys and values * `morphia.discriminator` * `morphia.discriminator-key` @@ -66,18 +66,19 @@ The choices here are simpler: 1. `className()`/`lowerClassName()` 2. `simpleName()`/`lowerSimpleName()` -Simple name is the fully qualified classname without the package name. These can all be accessed via their named methods on +Simple name is the class name without the package name. These can all be accessed via their named methods on link:++javadoc/dev/morphia/mapping/DiscriminatorFunction.html++[DiscriminatorFunction] and just like the `NamingStrategy` cases, if the provided options are not sufficient, you can implement your own by subclassing `DiscriminatorFunction` and implementing your own function. -=== Mapper selection +== Mapper selection * `morphia.mapper` Morphia supports two mapper implementations, selectable via configuration: 1. `reflection` *(default)* — the traditional reflection-based mapper. No additional dependencies required. -2. `critter` — a bytecode-generation mapper that produces `VarHandle`-based accessors at runtime via Gizmo, with automatic fallback to reflection if generation fails for a given type. Pre-generated models from the `critter-maven` plugin are used when available (AOT path), otherwise models are generated at JVM startup. +2. `critter` — a bytecode-generation mapper that produces bytecode to handle serialization rather than using reflection. +This option should give you better performance overall. Pre-generated models from the `critter-maven` plugin are used when available (AOT path), otherwise models are generated at JVM startup. To enable the critter mapper, add the following to your `META-INF/morphia-config.properties`: @@ -90,7 +91,7 @@ Or pass `-Dmorphia.mapper=critter` on the Maven command line when running tests. For production deployments, consider using the xref:maven-plugin.adoc[critter-maven plugin] to generate models at build time and eliminate the startup cost entirely. -=== User-defined Codecs +== User-defined Codecs * `morphia.codec-provider` @@ -114,13 +115,13 @@ will not only make it consistent with other configurable elements but will make the note below about using the ServiceLoader with Java 9 modules. ==== -==== Property Codecs +== Property Codecs As unusual as is the need for a custom codec to handle types, there are rare cases where how Morphia processes a property on entity needs to be customized. This processing is handled via the link:++javadoc/dev/morphia/mapping/codec/MorphiaPropertyCodecProvider.html++[MorphiaPropertyCodecProvider]. Morphia discovers these custom implementations via SPI the details of which won't be covered here. -=== Legacy Configuration +== Legacy Configuration Morphia can be configured in one of two ways: the legacy mode and the modern mode. The defaults in the configuration code will give you the modern configuration and is the recommended way to configure Morphia. However, if you're upgrading an older project, you very likely @@ -131,7 +132,7 @@ Using the legacy configuration is a matter of defining a few entries in your con you already have a `MorphiaConfig` in hand but would like to update it to reflect the legacy style configuration, you can call `.legacy()` on that reference and use the resulting `MorphiaConfig` instance. -=== Sample config files +== Sample config files .Complete with defaults [,txt] @@ -139,8 +140,6 @@ on that reference and use the resulting `MorphiaConfig` instance. include::example$complete-morphia-config.properties[] ---- ---- - .Minimal config file [,txt] ---- @@ -149,11 +148,10 @@ include::example$minimal-morphia-config.properties[] [NOTE] ==== -The minimum config is, indeed, an empty (or even nonexistant) file as there are defaults for each value. This is intended to "pave the +The minimum config is, indeed, an empty (or even nonexistent) file as there are defaults for each value. This is intended to "pave the on ramp" for those new to Morphia. It is expected that some of those values, notably the database and packages fields, will eventually be updated with more suitable values. ==== ---- .Legacy config file [,txt] @@ -161,13 +159,12 @@ be updated with more suitable values. include::example$legacy-morphia-config.properties[] ---- -[WARN] +[WARNING] ==== -The legacy query factory is deprecated and will be removed in 3.0. It is advisable to switch to the newer query filters based API now to -avoid breakage. +The legacy query factory has been removed in 3.0. Switch to the newer query filters based API. ==== -=== Some notes on ServiceLoader +== Some notes on ServiceLoader Morphia provides a number of extensibility points using https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html[the SPI mechanism] available in the JVM. This allows for seamless, config-free inclusion of different functionality. In general, this works without notice @@ -175,6 +172,7 @@ because most users will not need to implement such features and so needn't be bo lucky ones that *does* need to know *and* you use Java modules, please be aware that the usual services file in `META-INF/services` won't work. In order to export your service for Morphia to find you need an entry in your `module-info.java` file as shown below: -```java +[source,java] +---- provides dev.morphia.mapping.codec.MorphiaPropertyCodecProvider with com.foo.MyCodecProvider; -``` \ No newline at end of file +---- \ No newline at end of file diff --git a/docs/modules/ROOT/pages/deletes.adoc b/docs/modules/ROOT/pages/deletes.adoc index 74d8e2981e2..e27c9c29e45 100644 --- a/docs/modules/ROOT/pages/deletes.adoc +++ b/docs/modules/ROOT/pages/deletes.adoc @@ -1,4 +1,4 @@ -== Deletes += Deletes Queries are used to delete documents from the database as well. Using diff --git a/docs/modules/ROOT/pages/indexing.adoc b/docs/modules/ROOT/pages/indexing.adoc index fcb495b5ede..5197fd14f11 100644 --- a/docs/modules/ROOT/pages/indexing.adoc +++ b/docs/modules/ROOT/pages/indexing.adoc @@ -1,4 +1,4 @@ -== Indexing += Indexing Morphia provides annotations that allow developers to define indexes for a collection to be defined alongside the other mapping data on an entity's source. In addition to the familiar ascending/descending index types, Morphia and MongoDB support @@ -10,7 +10,7 @@ setting the `morphia.apply-indexes` to true in the xref:configuration.adoc[confi There are two ways to define indexes: at the class level and at the field level. -=== Class Level Indexes +== Class Level Indexes Class level indexing begins with the link:javadoc/dev/morphia/annotations/Indexes.html[@Indexes] annotation. This is a container annotation whose sole purpose is to hold a number of link:javadoc/dev/morphia/annotations/Index.html[@Index] annotations. @@ -38,7 +38,7 @@ public class IndexExample { } ---- -=== Fields +== Fields Which fields to index are defined with the link:javadoc/dev/morphia/annotations/Field.html[@Field] annotation. An arbitrary number of link:javadoc/dev/morphia/annotations/Field.html[@Field]s can be given but at least one must be present. @@ -48,23 +48,23 @@ annotations. For most index types, this value is validated by default. An exception is made for <<_text_indexing,text indexing>> as discussed below. -=== Index Options +== Index Options Options for an index are defined on the link:javadoc/dev/morphia/annotations/IndexOptions.html[@IndexOptions]. -More complete documenation can be found in the {docsRef}/reference/method/db.collection.createIndex/#options[manual]. +More complete documentation can be found in the {docsRef}/reference/method/db.collection.createIndex/#options[manual]. Using the options allows you to run indexing in the background, e.g. By default, creating an index blocks all other operations on a database. When building an index on a collection, the database that holds the collection is unavailable for read or write operations until the index build completes. For potentially long running index building operations, consider the **background** operation so that the MongoDB database remains available during the index building operation. The MongoDB {docsRef}/core/index-creation/#background-construction[manual] has more detail. -By default Morphia will attempt to validate the fields specified but in some cases that isn't desirable so you can turn it off via the options refernce. `IndexOptions` lets you define {docsRef}/core/index-ttl/[TTL], {docsRef}/core/index-sparse/[sparse], and {docsRef}/core/index-partial/[partial] indexes as well. `IndexOptions` can also be used to give an index a more human friendly name. +By default Morphia will attempt to validate the fields specified but in some cases that isn't desirable so you can turn it off via the options reference. `IndexOptions` lets you define {docsRef}/core/index-ttl/[TTL], {docsRef}/core/index-sparse/[sparse], and {docsRef}/core/index-partial/[partial] indexes as well. `IndexOptions` can also be used to give an index a more human friendly name. [NOTE] ==== Whether user specified or MongoDB generated, index names including their full namespace (i.e. database.collection) cannot be longer than the {docsRef}/reference/limits/#Index-Name-Length[Index Name Limit]. ==== -==== Partial Indexes +== Partial Indexes New in MongoDB 3.2, https://docs.mongodb.com/v3.2/core/index-partial/[partial indexes] only index the documents in a collection that meet a specified filter expression thereby reducing storage and maintenance costs. A partial filter is defined using a query as shown here: @@ -122,7 +122,7 @@ A wild card text index declaration would look like this: A collection can have at most one text index. ==== -=== Collation +== Collation Collation allows users to specify language-specific rules for string comparison such as rules for lettercase and accent marks. A collation can be defined using the `collation()` property on link:javadoc/dev/morphia/annotations/IndexOptions.html[@IndexOptions] diff --git a/docs/modules/ROOT/pages/kotlin.adoc b/docs/modules/ROOT/pages/kotlin.adoc index 24df0786ebe..17600c98ea3 100644 --- a/docs/modules/ROOT/pages/kotlin.adoc +++ b/docs/modules/ROOT/pages/kotlin.adoc @@ -1,4 +1,4 @@ -== Kotlin += Kotlin In general, your Kotlin types should work out of the box with Morphia. There are, however, a few interesting cases where they need a little extra help. @@ -35,4 +35,4 @@ This module should support any `ReadWriteProperty` type but is only currently tested against the `notNull()` case. All that is needed to enable this more targeted support is to simply add the new dependency to your project as shown above and it should magically "Just Work™". -If you find something that doesn't work in your Kotlin project, please file an xref:/issues-help.adoc[issue]. +If you find something that doesn't work in your Kotlin project, please file an xref:issues-help.adoc[issue]. diff --git a/docs/modules/ROOT/pages/lifeCycleMethods.adoc b/docs/modules/ROOT/pages/life-cycle-methods.adoc similarity index 86% rename from docs/modules/ROOT/pages/lifeCycleMethods.adoc rename to docs/modules/ROOT/pages/life-cycle-methods.adoc index f97404b6030..e03d92aaca0 100644 --- a/docs/modules/ROOT/pages/lifeCycleMethods.adoc +++ b/docs/modules/ROOT/pages/life-cycle-methods.adoc @@ -1,4 +1,4 @@ -== Life Cycle Methods += Life Cycle Methods There are various annotations which can be used to register callbacks on certain life cycle events. These include Pre/Post-Persist (Save), and Pre/Post-Load. @@ -8,13 +8,13 @@ These include Pre/Post-Persist (Save), and Pre/Post-Load. 3. `@PreLoad` - Called before mapping the document from the database to the entity; the Document is passed as an argument (you can add/remove/change values) 4. `@PostLoad` - Called after populating the entity with the values from the document -=== Examples +== Examples -https://github.com/MorphiaOrg/morphia/blob/master/morphia/src/test/java/dev/morphia/TestQuery.java[Here] is a one of the test classes. +{srcRef}/core/src/test/java/dev/morphia/TestQuery.java[Here] is a one of the test classes. -All parameters and return values are options in your implemented methods. +All parameters and return values are optional in your implemented methods. -==== Example +== Example Here is a simple example of an entity that always saves the Date it was last updated. Alternatively, the resulting serialized form can be passed back in just prior to sending the document to the database. @@ -38,7 +38,7 @@ class BankAccount { } ---- -=== EntityListeners +== EntityListeners If your application has more generalized life cycle events, these methods can be stored on classes external to your model. For example's sake, let's assume there's a need to digitally sign all documents before storing it in the database. diff --git a/docs/modules/ROOT/pages/mapping.adoc b/docs/modules/ROOT/pages/mapping.adoc index c74305b04a2..b0b245431a9 100644 --- a/docs/modules/ROOT/pages/mapping.adoc +++ b/docs/modules/ROOT/pages/mapping.adoc @@ -1,20 +1,20 @@ -== Mapping += Mapping -=== Classes +== Classes -Mapping is triggered by annotating your type with the link:javadoc/dev/morphia/annotations/Entity.html[@Entity] annotation.This -instructs Morphia to inspect your type compute various metadata items about it.If you wish use a particular type as "top level" type, -you will need to annotate one field with the link:javadoc/dev/morphia/annotations/Id.html[@Id] annotation.Not every type will need to +Mapping is triggered by annotating your type with the link:javadoc/dev/morphia/annotations/Entity.html[@Entity] annotation. This +instructs Morphia to inspect your type compute various metadata items about it. If you wish use a particular type as "top level" type, +you will need to annotate one field with the link:javadoc/dev/morphia/annotations/Id.html[@Id] annotation. Not every type will need to serve as a top level type (read: be mapped to a collection) and so this ID field is optional with the caveat mentioned in the call out -note below.Top level types have their own collections whose names can be mapped via the `value` parameter.Leaving this value +note below. Top level types have their own collections whose names can be mapped via the `value` parameter. Leaving this value blank will leave Morphia free to compute the collection name as defined by the collection naming strategy defined in -link:javadoc/dev/morphia/mapping/MapperOptions.html[MapperOptions].That default is currently the camel case value of the class's -simple name.For example, to map a `UserProfile` entity under this strategy, the collection name would be mapped to `userProfile`. +link:javadoc/dev/morphia/config/MorphiaConfig.html[MorphiaConfig]. That default is currently the camel case value of the class's +simple name. For example, to map a `UserProfile` entity under this strategy, the collection name would be mapped to `userProfile`. Any type annotated with link:javadoc/dev/morphia/annotations/Entity.html[@Entity] may optionally have a field annotated with -link:javadoc/dev/morphia/annotations/Id.html[@Id].The type of the field can be any type so long as Morphia, or the driver, has a codec -that can map the data to and from mongodb.When mapping an entity, one can also define xref:indexing.adoc[indexes] and -xref:schemaValidation.adoc[schema validations] as part of the entity declaration as well. +link:javadoc/dev/morphia/annotations/Id.html[@Id]. The type of the field can be any type so long as Morphia, or the driver, has a codec +that can map the data to and from mongodb. When mapping an entity, one can also define xref:indexing.adoc[indexes] and +xref:schema-validation.adoc[schema validations] as part of the entity declaration as well. [NOTE] ==== @@ -34,7 +34,7 @@ perform proper updates on previously persisted entities. Without that ID Morphi document in the database. ==== -==== Constructors +== Constructors Morphia has traditionally required a 0-argument constructor on any mapped entity. In fact, Morphia still prefers to use such a constructor should one be available. @@ -45,7 +45,7 @@ That is, every field must be represented in the constructor signature. 2. The names of the arguments must match the names of the fields. Here, there is a bit of flexibility. The argument name can match either the field name as found in the source or the mapped name as determined by any `@Property` annotation. -While this is likely to be the most common case as it is the simplest, for various this won't always be possible or preferable. +While this is likely to be the most common case as it is the simplest, for various reasons this won't always be possible or preferable. If a constructor argument name can't mirror the field name, using the link:javadoc/dev/morphia/annotations/Name.html[@Name] annotation, an explicit name can be given so that the argument can be properly matched to a field. @@ -64,7 +64,7 @@ For maven users, it's as simple as adding one line to the Kotlin maven plugin `< true ---- -=== External types +== External types Sometimes persisted types come from external libraries whose source is either unavailable or simply can't be modified. Using these types would be impossible give then annotation requirements as stated above. @@ -127,7 +127,7 @@ The mix-in type can happily be ignored once you're done with mapping. This API is experimental and is likely to shift a bit as it sees usage and feedback from the community. ==== -=== Versioning +== Versioning Entities can be versioned to ensure that changes are applied serially and that no other processes are modifying an object in between the time it's fetched, modified, and written back to the database. To achieve this, simply add a field to a type, it can be a `long` or a @@ -142,7 +142,7 @@ Morphia checks the value of the version field or that the ID is null in order pr If neither of these conditions are true, the entity will not be persisted. ==== -=== Fields +== Fields By default, any non-static field on a mapped class will be processed for persistence. If a field is to be excluded from the mapping, it can be decorated with the `transient` keyword, annotated with @@ -160,12 +160,12 @@ Similarly, if data is only intended to be loaded from the database but never wri If you do not specify a name via `@Property`, the default field naming strategy will be used. The default strategy is to use the field's name as defined in the source. -This strategy can be changed globally via the field naming strategy option on -link:javadoc/dev/morphia/mapping/MapperOptions.html[MapperOptions]. +This strategy can be changed globally via the field naming strategy option configured via +link:javadoc/dev/morphia/config/MorphiaConfig.html[MorphiaConfig]. Simple indexes can be defined on a field if all that is needed for the index is a single field. This can be done via the link:javadoc/dev/morphia/annotations/Indexed.html[@Indexed] annotation. -=== Methods +== Methods [WARNING] ==== @@ -175,7 +175,7 @@ if you encounter such a case. ==== As of 2.2, mapping information can be defined on methods instead of fields. -All the same rules apply, simply the location of the annotations are moved to the getters and/or setters.Annotations can live on either the `get` or the `set` method and Morphia will detect them. +All the same rules apply, simply the location of the annotations are moved to the getters and/or setters. Annotations can live on either the `get` or the `set` method and Morphia will detect them. If the same annotation is applied to both the `get` and the `set` behavior is unpredictable so care should be taken to avoid such a scenario. Customs in other libraries tend to favor annotating the `get` methods and this is also recommended here for consistency. @@ -183,19 +183,19 @@ In order for methods to be considered as definitions of persistable properties, This has some very basic rules for your methods: 1. `get` methods take no parameters -2. `set` methods take one parameter and the type of that parameter should generally match the return type of the getter.These setter methods also return void. +2. `set` methods take one parameter and the type of that parameter should generally match the return type of the getter. These setter methods also return void. 3. If a property is a boolean type, the getter often uses `is` rather than `get` yielding a method named, e.g., `isEnabled()` rather than `getEnabled()`. 4. The type of the property is determined by the return value of the getter. 5. The name of the property is determined by stripping the `get` prefix (or `is` for boolean types) and lower casing the first letter. This is the default name of the property subject to property naming rules as defined in -link:javadoc/dev/morphia/mapping/MapperOptions.html[MapperOptions] +link:javadoc/dev/morphia/config/MorphiaConfig.html[MorphiaConfig] -To enable method mapping, a method has been added to link:javadoc/dev/morphia/mapping/MapperOptions.Builder.html[MapperOptions.Builder] +To enable method mapping, a method has been added to link:javadoc/dev/morphia/config/MorphiaConfig.html[MorphiaConfig] allowing for the configuration of either field or method mapping. [NOTE] ==== -Mapping is currently done via either fields or by methods.It is not currently allowed to map using both schemes simultaneously.This will +Mapping is currently done via either fields or by methods. It is not currently allowed to map using both schemes simultaneously. This will likely change in the future but for now is not allowed. ==== diff --git a/docs/modules/ROOT/pages/maven-plugin.adoc b/docs/modules/ROOT/pages/maven-plugin.adoc index 461bb7dfedc..82526a13256 100644 --- a/docs/modules/ROOT/pages/maven-plugin.adoc +++ b/docs/modules/ROOT/pages/maven-plugin.adoc @@ -1,11 +1,11 @@ -== Maven Plugin += Maven Plugin The `critter-maven` plugin generates Morphia entity models and property accessors at build time (AOT — ahead of time), so they are ready on the classpath before your application starts. Without the plugin, Morphia generates the same models at each JVM startup. The plugin is entirely optional; the runtime fallback produces identical results. It is recommended to use the plugin, however. -=== Why use it? +== Why use it? [cols="1,1"] |=== @@ -26,7 +26,7 @@ The plugin is entirely optional; the runtime fallback produces identical results Both paths generate the bytecode necessary to manage your entities. The plugin simply moves the generation work from JVM startup to build time. -=== Setup +== Setup Add the plugin to your `pom.xml` and set `morphia.mapper=critter` in your config: @@ -55,14 +55,14 @@ morphia.mapper=critter When `morphia.mapper=critter` is active and the plugin has run, Morphia loads the pre-generated models automatically — no code changes required. -=== Goals +== Goals -==== `generate-models` (default phase: `process-classes`) +== `generate-models` (default phase: `process-classes`) Reads compiled `.class` files from `${project.build.outputDirectory}` and writes generated entity model and accessor classes to `target/generated-classes/critter`. This is the standard goal for most projects. It has no user-configurable parameters. -=== How it fits together +== How it fits together [source] ---- diff --git a/docs/modules/ROOT/pages/migrating.adoc b/docs/modules/ROOT/pages/migrating.adoc index b6617646a60..25d014b9d94 100644 --- a/docs/modules/ROOT/pages/migrating.adoc +++ b/docs/modules/ROOT/pages/migrating.adoc @@ -2,7 +2,7 @@ == Migrating to 3.0 -More detailed information will be made available once those details stabilize but at the moment there two things to keep an eye on: +More detailed information will be made available once those details stabilize but at the moment there are two things to keep an eye on: 1. Upgrades will be as automatic as they can be made to be via openrewrite recipes that should take care of the almost all of the work if things go as well as hoped. @@ -15,7 +15,7 @@ driver version of 5.x or greater. If you need a 4.x driver for some reason, you support 5.x and greater. In preparation for 3.0, deprecations will be incrementally made in the 2.5.x line with replacements where feasible. Updating away from these deprecations will make the transition to 3.0 much smoother. In the cases where the replacements can not feasibly be provided, migration scripts will be available as part of the 3.0 release to help reduce the impact of such changes. Bug -fixes will continue to be made on the 2.4.x series and 2 .5.x as necessary but the primary focus remains on 3.x. +fixes will continue to be made on the 2.4.x series and 2.5.x as necessary but the primary focus remains on 3.x. == Migrating to 2.4 @@ -60,9 +60,10 @@ all sorts. In our case, it's primarily just removing the `experimental` segment https://github.com/MorphiaOrg/morphia/blob/master/upgrading/UpgradeFrom22to23.yml[script] and save it as `rewrite.yml` in the root of your project. Once that is done, run the following command: -```shell +[source,shell] +---- mvn org.openrewrite.maven:rewrite-maven-plugin:4.37.0:runNoFork -DactiveRecipes=dev.morphia.UpgradeFrom22to23 -``` +---- This script will update the packages to reflect their new names. It will also update your pom to the latest Morphia version for you if that has not been updated yet. @@ -74,9 +75,10 @@ force than the openrewrite approach (it's literally just doing string replacemen kotlin user, you'll want to use this approach as openrewrite does not currently support kotlin source files. To run this script, use the following command: -```shell +[source,shell] +---- jbang https://github.com/MorphiaOrg/morphia/blob/master/upgrading/UpgradeFrom22to23.kt -``` +---- You will likely be asked to specify the level of trust you have for this script and the MorphiaOrg github organization. Choose whichever level you're comfortable with. @@ -103,20 +105,22 @@ However, it will still be possible to configure your application with the old se update to this new configuration approach, rather than using `MappingOptions.legacy().build()` as you have perhaps been doing, simply replace it with something like the following: -```java +[source,java] +---- MapperOptions.builder() .discriminatorKey("className") .discriminator(DiscriminatorFunction.className()) .collectionNaming(NamingStrategy.identity()) .propertyNaming(NamingStrategy.identity()) -``` +---- This will preserve the older mappings used by your data while enabling the modern query API implementation. Some users will have date/time data stored under an older storage scheme. Those users will also want to include the following option: -```java +[source,java] +---- .dateStorage(DateStorage.SYSTEM_DEFAULT) -``` +---- == Migrating to 2.0 diff --git a/docs/modules/ROOT/pages/queries.adoc b/docs/modules/ROOT/pages/queries.adoc index ea14205341a..a693fbc6b68 100644 --- a/docs/modules/ROOT/pages/queries.adoc +++ b/docs/modules/ROOT/pages/queries.adoc @@ -1,4 +1,4 @@ -== Queries += Queries Morphia provides link:javadoc/dev/morphia/query/Query.html[Query] class to build a query and map the results back to instances of your entity classes and attempts to provide as much type safety and validation as possible. To create the `Query`, we invoke the following code: @@ -10,7 +10,7 @@ Query query = datastore.find(Product.class); `find()` returns an instance of `Query` which we can use to build a query. -=== `filter()` +== `filter()` The most significant method `filter(Filter...)`. This method takes a number of filters to apply to the query being built. @@ -30,7 +30,7 @@ query.filter(Filters.gte("price", 1000)); This will append the new criteria to any existing criteria already defined. You can define as many filters in one call as you'd like or you may choose to append them in smaller groups based on whatever query building logic your application might have. -=== Complex Queries +== Complex Queries Of course, queries are usually more complex than single field comparisons. Morphia offers both `and()` and `or()` to build up more complex queries. @@ -62,12 +62,12 @@ This generates an implicit `and` across the field comparisons. There is more to querying than simply filtering against different document values. Listed below are some of the options for modifying the query results in different ways. -=== Projections +== Projections {docsRef}/tutorial/project-fields-from-query-results/[Projections] allow you to return only a subset of the fields in a document. This is useful when you need to only return a smaller view of a larger object. Borrowing from the -{srcRef}/morphia/src/test/java/dev/morphia/TestQuery.java[unit tests], this is an example of this feature in action: +{srcRef}/core/src/test/java/dev/morphia/TestQuery.java[unit tests], this is an example of this feature in action: [source,java] ---- @@ -96,7 +96,7 @@ To save such instances back consider using link:++javadoc/dev/morphia/Datastore.html#merge(T)++[Datastore#merge(T)] ==== -=== Limiting and Skipping +== Limiting and Skipping Pagination of query results is often done as a combination of skips and limits. Morphia offers `FindOptions.limit(int)` and @@ -115,7 +115,7 @@ This query will skip the first element and take up to the next 10 items found by There's a caveat to using skip/limit for pagination, however. See the {docsRef}/reference/method/cursor.skip[skip] documentation for more detail. -=== Ordering +== Ordering Ordering the results of a query is done via link:++javadoc/dev/morphia/query/FindOptions.html#sort(dev.morphia.query.Sort...)++[FindOptions.sort(Sort...)], etc. @@ -130,12 +130,12 @@ getDs().find(User.class) .tryNext(); ---- -=== Tailable Cursors +== Tailable Cursors If you have a {docsRef}/core/capped-collections/[capped collection] it's possible to "tail" a query so that when new documents are added to the collection that match your query, they'll be returned by the {docsRef}/reference/glossary/#term-tailable-cursor[tailable cursor]. An example of this feature in action can be found in the -{srcRef}/morphia/src/test/java/dev/morphia/TestQuery.java[unit tests] in the `testTailableCursors()` test: +{srcRef}/core/src/test/java/dev/morphia/TestQuery.java[unit tests] in the `testTailableCursors()` test: [source,java] ---- @@ -160,7 +160,7 @@ If the collection already exists and is not capped, you will have to manually 2. Since this `Iterator` is backed by a tailable cursor, `hasNext()` and `next()` will block until a new item is found. In this version of the unit test, we tail the cursor waiting to pull out objects until we have 10 of them and then proceed with the rest of the application. -=== Polymorphic Queries +== Polymorphic Queries By default, Morphia will only return documents of the type given in `find()`. However, if you want to retrieve subtypes as well, you can enable this in `MorphiaConfig` via @@ -172,7 +172,7 @@ Queries by ID will ignore this setting since such queries are filtering by a spe potential performance hits due to the wider scope of the query filter. ==== -=== Supported Operators +== Supported Operators Every effort is made to provide 100% coverage of all the operators offered by MongoDB. Below is listed all the currently supported operators. To see an example of an operator in action, click through to see the test cases for that operator. diff --git a/docs/modules/ROOT/pages/query-filters.adoc b/docs/modules/ROOT/pages/query-filters.adoc index 1012b29a9ce..d150e003a2b 100644 --- a/docs/modules/ROOT/pages/query-filters.adoc +++ b/docs/modules/ROOT/pages/query-filters.adoc @@ -1,3 +1,5 @@ +:page-partial: + [%header,cols="1,2,3"] |=== |Operator|Docs|Test Examples diff --git a/docs/modules/ROOT/pages/quicktour.adoc b/docs/modules/ROOT/pages/quicktour.adoc index 4a35cb7f1be..d008519edc3 100644 --- a/docs/modules/ROOT/pages/quicktour.adoc +++ b/docs/modules/ROOT/pages/quicktour.adoc @@ -19,8 +19,7 @@ final Datastore datastore = Morphia.createDatastore(MongoClients.create()); This snippet creates the Morphia instance we'll be using in our simple application. The `Morphia` class is a factory for `Datastore` instances, if you will. Given this minimal setup, Morphia will use a database named `morphia` and will scan your entire classpath for entities to map. Obviously this full scan is less than ideal long term but serves -to get you up and running quickly. For a more complete discussion on configuring Morphia, please see the xref:configuration.adoc for -more details. +to get you up and running quickly. For a more complete discussion on configuring Morphia, please see the xref:configuration.adoc[configuration guide]. This default setup will connect to the mongod running on the local machine using the default port of `27017`. When Morphia scans looking for entities, it will for classes annotated with link:javadoc/dev/morphia/annotations/Entity.html[@Entity] (which we'll cover shortly) and @@ -76,9 +75,9 @@ link:javadoc/dev/morphia/annotations/Entity.html[@Entity] annotation so we know In the annotation, you'll see `"employees"`. By default, Morphia will use the camel case class name as the collection name. If you pass a String instead, it will use that value for the collection name. -In this case, all `Containers` instances will be saved in to the `employees` +In this case, all `Employee` instances will be saved in to the `employees` collection instead. -There is a little more to this annotation but the link:javadoc/dev/morphia/annotations/Entity.html[@Entity] javadoc covers those details . link:javadoc/dev/morphia/annotations/Entity.html[@Entity] should be used on any type you want Morphia to map including embedded types. +There is a little more to this annotation but the link:javadoc/dev/morphia/annotations/Entity.html[@Entity] javadoc covers those details. link:javadoc/dev/morphia/annotations/Entity.html[@Entity] should be used on any type you want Morphia to map including embedded types. Embedded types are not required to have an link:javadoc/dev/morphia/annotations/Id.html[@Id] annotated field. The link:javadoc/dev/morphia/annotations/Indexes.html[@Indexes] annotation lists which indexes Morphia should create. @@ -106,7 +105,7 @@ These referenced entities must already be saved or at least have an ID assigned [NOTE] ==== -There is a newer approach for defining references that is explained more fully xref:indexing.adoc[here]. +There is a newer approach for defining references that is explained more fully xref:references.adoc[here]. ==== == Saving Data @@ -140,7 +139,7 @@ As you can see, we just need to create and save the other Employees then we can Morphia takes care of saving the keys in Elmer's document that refer to Daffy and Pepé. Updating data in MongoDB is as simple as updating your Java objects and then calling `datastore.save()` with them again. For bulk updates (e.g., everyone gets a raise!) this is not the most efficient way of doing updates. -It is possible to update directly in the database without having to pull in every document, convert to Java objects, update, convert back to a document, and write back to MongoDB.But in order to show you that piece, first we need to see how to query. +It is possible to update directly in the database without having to pull in every document, convert to Java objects, update, convert back to a document, and write back to MongoDB. But in order to show you that piece, first we need to see how to query. == Querying @@ -166,14 +165,14 @@ Here's how to do that: [source,java] ---- -underpaid = datastore.createQuery(Employee.class) +underpaid = datastore.find(Employee.class) .filter(Filters.lte("salary", 30000)) .iterator() .toList(); ---- -Morphia supports all the query filters defined in the Mongodb query language. -You can find helper methods for all these filers on the +Morphia supports all the query filters defined in the MongoDB query language. +You can find helper methods for all these filters on the link:javadoc/dev/morphia/query/filters/Filters.html[Filters class]. The `filter()` method can take as many `Filter` references as you need to define your query. diff --git a/docs/modules/ROOT/pages/references.adoc b/docs/modules/ROOT/pages/references.adoc index 014b734bca7..b0a1bafb03b 100644 --- a/docs/modules/ROOT/pages/references.adoc +++ b/docs/modules/ROOT/pages/references.adoc @@ -1,14 +1,14 @@ -== References += References MongoDB tries to encourage self-contained documents so that data can be fetched much more efficiently via single reads from the database. However not every data model or application can adhere to this philosophy in its entirety. As such, MongoDB supports -{docsRef}/reference/database-references/[database references].Morphia supports two styles of defining references: +{docsRef}/reference/database-references/[database references]. Morphia supports two styles of defining references: 1. the link:javadoc/dev/morphia/annotations/Reference.html[@Reference] annotation 2. an experimental wrapper type link:javadoc/dev/morphia/mapping/experimental/MorphiaReference.html[MorphiaReference]. -=== Using the annotation +== Using the annotation The annotation based approach is the traditional approach. The link:javadoc/dev/morphia/annotations/Reference.html[@Reference] can be applied to any property whose type is a mappable Entity type. diff --git a/docs/modules/ROOT/pages/schemaValidation.adoc b/docs/modules/ROOT/pages/schema-validation.adoc similarity index 89% rename from docs/modules/ROOT/pages/schemaValidation.adoc rename to docs/modules/ROOT/pages/schema-validation.adoc index b097a67099c..108649fd05f 100644 --- a/docs/modules/ROOT/pages/schemaValidation.adoc +++ b/docs/modules/ROOT/pages/schema-validation.adoc @@ -1,8 +1,8 @@ -== Schema Validation += Schema Validation Morphia provides annotations that allow developers to define document validations for a collection to be defined alongside the other mapping data on an entity's source. {docsRef}/core/schema-validation/[Schema validation] provides the capability to perform schema validation during updates and insertions. Validation rules are on a per-collection basis and can be defined via annotations just like indexes are. Morphia will automatically -apply mapped document validations when `morphia.apply-document-validations` is set to true in the xref:configuration.adoc[configuration +apply mapped document validation rules when `morphia.apply-document-validations` is set to true in the xref:configuration.adoc[configuration file]. Below we have a basic entity definition. diff --git a/docs/modules/ROOT/pages/sharding.adoc b/docs/modules/ROOT/pages/sharding.adoc index 3c49f4505c0..057083ad362 100644 --- a/docs/modules/ROOT/pages/sharding.adoc +++ b/docs/modules/ROOT/pages/sharding.adoc @@ -1,10 +1,10 @@ -== Sharding += Sharding [NOTE] ==== -Sharding suport is new in 2.3 and should be considered experimental. +Morphia supports sharding via the `@ShardKeys` annotation. While all tests currently pass, the form and function of the sharding support might change as issues arise and any usability concerns are addressed. -This is feature is safe to use just be aware that this API might change based on user feedback. +This feature is safe to use just be aware that this API might change based on user feedback. ==== Much like the indexing support, Morphia provides a number of annotations to help in the definition and use of sharded collections. @@ -12,13 +12,13 @@ You don't need to use Morphia to shard your collections, but if your collection Documentation on how to choose a proper shard key can be found in the {docsRef}/sharding[manual]. -=== Shard Definition +== Shard Definition Sharding definitions are driven by the link:javadoc/dev/morphia/annotations/ShardKeys.html[@ShardKeys] annotation. This annotation takes two values: the shard keys themselves as defined by the link:javadoc/dev/morphia/annotations/ShardKey.html[@ShardKey] annotation and the options to apply when sharding the collection via the link:javadoc/dev/morphia/annotations/ShardOptions.html[@ShardOptions] annotation. -An shard definition might look something like this. +A shard definition might look something like this. [source,java] ---- @@ -55,16 +55,16 @@ If you find yourself needing to mutate one of those properties, consult the {doc Morphia does not currently support redefining the shard key definition entirely. ==== -=== Sharding Options +== Sharding Options `@ShardKeys` also has an `options` field which takes a link:javadoc/dev/morphia/annotations/ShardOptions.html[@ShardOptions]. Using this annotation, you can configure the number of initial shards, {docsRef}/core/hashed-sharding/#shard-an-empty-collection[presplit the hashed zones], or {docsRef}/core/sharding-shard-key/#unique-indexes[enforce uniqueness] in your shard key. -=== How is it used? +== How is it used? Once you have your sharding configured, you have the choice of manually sharding it via the mongo shell or having Morphia shard it for you. For the latter, there is a new method link:++javadoc/dev/morphia/Datastore.html#shardCollections()++[shardCollections()] that will do -thisfor you. It should be noted here that if your collection is not empty, there are certain administrative tasks you must perform on the collection first that Morphia does *not* handle. +this for you. It should be noted here that if your collection is not empty, there are certain administrative tasks you must perform on the collection first that Morphia does *not* handle. You can find those details in the server documentation. Once your collection is sharded, Morphia uses the shard key definition to update certain operations (such as saves/upserts and find-and-modify among others) to include the relevant shard key information so that mongodb can quickly and efficiently find the documents in the database. diff --git a/docs/modules/ROOT/pages/textSearches.adoc b/docs/modules/ROOT/pages/text-searches.adoc similarity index 78% rename from docs/modules/ROOT/pages/textSearches.adoc rename to docs/modules/ROOT/pages/text-searches.adoc index ca7bb80cf1e..23d98044d6e 100644 --- a/docs/modules/ROOT/pages/textSearches.adoc +++ b/docs/modules/ROOT/pages/text-searches.adoc @@ -1,4 +1,4 @@ -== Text Searches += Text Searches Morphia also supports MongoDB's text search capabilities. In order to execute a text search against a collection, the collection must have a {docsRef}/core/index-text/[text index] defined first. @@ -19,7 +19,7 @@ public static class Greeting { The `$**` value tells MongoDB to create a text index on all the text fields in a document. A more targeted index can be created, if desired, by explicitly listing which fields to index. Once the index is defined, we can start querying against it like this -{srcRef}/legacy-tests/src/test/java/dev/morphia/query/TestTextSearching.java[test] does: +{srcRef}/core/src/test/java/dev/morphia/query/TestTextSearching.java[test] does: [source,java] ---- @@ -31,14 +31,14 @@ datastore.save(new Greeting("good morning", "english"), new Greeting("good night", "english"), new Greeting("good riddance", "english"), new Greeting("guten Morgen", "german"), - new Greeting("guten Tag", "german")), + new Greeting("guten Tag", "german"), new Greeting("gute Nacht", "german")); -List good = getDs().find(Greeting.class) - .filter(text("good")) - .execute(new FindOptions() - .sort(ascending("_id"))) - .toList(); +List good = datastore.find(Greeting.class) + .filter(text("good")) + .iterator(new FindOptions() + .sort(ascending("_id"))) + .toList(); Assert.assertEquals(4, good.size()); ---- @@ -51,11 +51,11 @@ If you would like to restrict your search to a specific language, that can also [source,java] ---- -datastore.find(Greeting.class) +datastore.find(Greeting.class, new FindOptions() + .sort(ascending("_id"))) .filter(text("good") .language("english")) - .execute(new FindOptions() - .sort(ascending("_id"))) + .iterator() .toList(); ---- diff --git a/docs/modules/ROOT/pages/transactions.adoc b/docs/modules/ROOT/pages/transactions.adoc index a62d1f4e5ed..1653971a0b0 100644 --- a/docs/modules/ROOT/pages/transactions.adoc +++ b/docs/modules/ROOT/pages/transactions.adoc @@ -1,4 +1,4 @@ -== Transactions += Transactions Starting with MongoDB version 4.0, multi-document transactions are now supported on replica sets. Morphia 2.0 introduced a simple mechanism to access this functionality. diff --git a/docs/modules/ROOT/pages/update-operators.adoc b/docs/modules/ROOT/pages/update-operators.adoc index 186b138adec..ba21be2b14f 100644 --- a/docs/modules/ROOT/pages/update-operators.adoc +++ b/docs/modules/ROOT/pages/update-operators.adoc @@ -1,3 +1,5 @@ +:page-partial: + [%header,cols="1,2,3"] |=== |Operator|Docs|Test Examples diff --git a/docs/modules/ROOT/pages/updates.adoc b/docs/modules/ROOT/pages/updates.adoc index 606957f0860..38ffe9b9cfb 100644 --- a/docs/modules/ROOT/pages/updates.adoc +++ b/docs/modules/ROOT/pages/updates.adoc @@ -1,6 +1,6 @@ -== Updates += Updates -Updates in 2.0, are issued using a `Query` instance . These update operations are executed on the server without fetching any documents across the wire. +Updates are issued using a `Query` instance. These update operations are executed on the server without fetching any documents across the wire. Update operations are defined using a set of functions as defined on link:javadoc/dev/morphia/query/updates/UpdateOperators.html[UpdateOperators]. In our examples, we'll be using the following model: @@ -36,7 +36,7 @@ public class Address } ---- -=== set()/unset() +== set()/unset() To change the name of the hotel, one would use something like this: @@ -57,8 +57,7 @@ To change the name of the city in the address, one would use something like this ---- datastore .find(Hotel.class) - .update(UpdateOperators.set("address.city", "Ottawa")) - execute(); + .update(UpdateOperators.set("address.city", "Ottawa")); ---- Values can also be removed from documents as shown below: @@ -67,13 +66,12 @@ Values can also be removed from documents as shown below: ---- datastore .find(Hotel.class) - .update(UpdateOperators.unset("name")) - execute(); + .update(UpdateOperators.unset("name")); ---- After this update, the name of the hotel would be `null` when the entity is loaded. -=== Multiple Updates +== Multiple Updates By default, an update operation will only update the first document matching the query. This behavior can be modified via the optional @@ -83,12 +81,11 @@ link:javadoc/dev/morphia/UpdateOptions.html[UpdateOptions] parameter on `execute ---- datastore .find(Hotel.class) - .inc("stars") - .execute(new UpdateOptions() - .multi(true)); + .update(new UpdateOptions() + .multi(true), UpdateOperators.inc("stars")); ---- -=== Upserts +== Upserts In some cases, updates are issued against a query that might not match any documents. In these cases, it's often fine for those updates to simply pass with no effect. @@ -98,23 +95,22 @@ Examples of this might include user high scores, e.g. In cases like this, we hav [source,java] ---- datastore - .find(Hotel.class) + .find(Hotel.class, new UpdateOptions() + .upsert(true)) .filter(gt("stars", 100)) - .update() - .execute(new UpdateOptions() - .upsert(true)); + .update(); // creates { "_id" : ObjectId("4c60629d2f1200000000161d"), "stars" : 50 } ---- -=== Checking results +== Checking results In all this one thing we haven't really looked at is how to verify the results of an update. The `execute()` method returns an instance of `com.mongodb.client.result.UpdateResult`. Using this class, you can get specific numbers from the update operation as well as any generated ID as the result of an upsert. -=== Returning the updated entity +== Returning the updated entity There are times when a document needs to be updated and also fetched from the database. In the server documentation, this is referred to as {docsRef}/reference/method/db.collection.findAndModify/[findAndModify]. @@ -127,13 +123,12 @@ This can be changed by passing in a `ModifyOptions` reference to the operation: [source,java] ---- datastore - .find(Hotel.class) - .modify(UpdateOperators.set("address.city", "Ottawa")) - execute(new ModifyOptions() - .returnDocument(ReturnDocument.AFTER)); + .find(Hotel.class, new ModifyOptions() + .returnDocument(ReturnDocument.AFTER)) + .modify(UpdateOperators.set("address.city", "Ottawa")); ---- -=== Merges +== Merges A specialized form of an update is the link:++javadoc/dev/morphia/Datastore.html#merge(T)++[merge()] operation. A common case in scenarios where multiple subsystems or applications share a database is where one part of the system might only have part of a larger entity. e.g., a @@ -155,11 +150,11 @@ Regardless of whether this value is set, `merge()` will issue a `find()` for tha Without using `unsetMissing()`, this is useful for merging the in memory state with what's in the database. With this value set, the two should be identical, of course. -=== Supported Operators +== Supported Operators Every effort is made to provide 100% coverage of all the operators offered by MongoDB. Below is listed all the currently supported operators. To see an example of an operator in action, click through to see the test cases for that operator. If an operator is missing and you think it should be included, please file an https://github.com/MorphiaOrg/morphia/issues[issue] for that operator. -.Filters +.Update Operators include::update-operators.adoc[] diff --git a/docs/modules/ROOT/pages/updating-old.adoc b/docs/modules/ROOT/pages/updating-old.adoc index 58d86d5c0b0..f86cd74d3e8 100644 --- a/docs/modules/ROOT/pages/updating-old.adoc +++ b/docs/modules/ROOT/pages/updating-old.adoc @@ -1,3 +1,10 @@ +[WARNING] +==== +This page documents the legacy update API that was removed in Morphia 3.0. +It is preserved here for users migrating from 2.x. +For the current update API, see xref:updates.adoc[Updates]. +==== + = Updating (Legacy) There are two basic ways to update your data: insert/save a whole Entity or issue an update operation.