Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public/
resources/_gen/
.hugo_build.lock
10 changes: 10 additions & 0 deletions docs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.PHONY: build serve clean

build:
hugo --minify

serve:
hugo server -D

clean:
rm -rf public/
19 changes: 19 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Morphia Documentation

This folder contains the Hugo-based documentation for Morphia.

## Building

```bash
# Install Hugo (https://gohugo.io/installation/)
# Then run:
make serve # For local development
make build # For production build
```

## Structure

- `content/` - Markdown documentation files
- `layouts/` - HTML templates
- `static/` - Static assets (CSS, images, etc.)
- `data/` - Data files for menus and configuration
11 changes: 0 additions & 11 deletions docs/antora.yml

This file was deleted.

5 changes: 5 additions & 0 deletions docs/archetypes/default.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
100 changes: 100 additions & 0 deletions docs/content/features/aggregations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: "Aggregations"
weight: 9
description: "Learn how to use MongoDB's aggregation framework with Morphia to define pipelines and transform data."
---

## Aggregations

The [aggregation framework](https://docs.mongodb.com/manual/aggregation) 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 [documentation](https://docs.mongodb.com/manual/aggregation) has extensive tutorials on such details.
Rather, this guide will focus on the Morphia API. The examples shown here are taken from the
[tests](https://github.com/MorphiaOrg/morphia/blob/master/morphia/src/test/java/dev/morphia/aggregation/AggregationTest.java) in Morphia itself. You can find the full list in the [Supported Operators](#supported-operators) section.

Writing an aggregation pipeline starts just like writing a standard query.
As with querying, we start with the `Datastore`:

```java
// Example aggregation code
// See TestDocsExamples.java for full examples
```

`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 [pipeline](https://docs.mongodb.com/manual/core/aggregation-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

Aggregation pipelines are comprised of a series stages.
Our example here with the `group()` stage. This method is the Morphia equivalent of the
[$group](https://docs.mongodb.com/manual/reference/operator/aggregation/group/) operator. This stage, as the name suggests, groups together documents based on
various criteria. In this example, we are defining the group ID as the `author` field which will collect all the books by the author
together.

The next step defines a new field, `books` comprised of the titles of the books found in each document. (For reference, this example is
the Morphia equivalent of an [example](https://docs.mongodb.com/manual/reference/operator/aggregation/group/#group-title-by-author) found in the aggregation tutorials.) This results in a series of documents that look like this:

```json
{ "_id" : "Homer", "books" : [ "The Odyssey", "Iliad" ] }
{ "_id" : "Dante", "books" : [ "The Banquet", "Divine Comedy", "Eclogues" ] }
```

### 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.
Given this type, Morphia will map each document in the results and return it.
Additionally, you can also include some options to `execute()`.
We can use the various options on the
[AggregationOptions](/javadoc/dev/morphia/aggregation/AggregationOptions.html) class to configure how we want the pipeline to execute.

#### $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. [$out](https://docs.mongodb.com/manual/reference/operator/aggregation/out/) is an operator that allows the results of a pipeline to be stored in to a named collection.
This collection can not be sharded or a capped collection, however. This collection, if it does not exist, will be created upon execution of the pipeline.

{{% notice warning %}}
Any existing data in the collection will be replaced by the output of the aggregation.
{{% /notice %}}

An example aggregation using the `$out` stage looks like this:

```java
// Example using $out stage
// See TestDocsExamples.java for full examples
```

You'll note that `out()` is the final stage. `$out` and `$merge` must be the final stage in our pipeline. We pass a type to `out()`
that reflects the collection we want to write our output to. Morphia will use the type-to-collection mapping you've defined when mapping
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](https://docs.mongodb.com/manual/reference/operator/aggregation/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
overwrite any existing documents and replace them with the results of the pipeline. `$merge`, however, can deposit these new results alongside existing data and update existing data.

Using `$merge` might look something like this:

```java
// Example using $merge stage
// See TestDocsExamples.java for full examples
```

Much like `out()` above, for `merge()` we pass in a collection information but here we are also passing in which database to find/create
the collection in. A merge is slightly more complex and so has more options to consider.
In this example, we're merging in to the `budgets` collection in the `reporting` database and merging any existing documents based on the`_id` as denoted using the `on()` method.
Because there may be existing data in the collection, we need to instruct the operation how to handle those cases.
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
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.

If an operator is missing and you think it should be included, please file an [issue](https://github.com/MorphiaOrg/morphia/issues) for that operator.

For detailed information on stages and expressions, see the MongoDB [Aggregation Pipeline Operators documentation](https://docs.mongodb.com/manual/reference/operator/aggregation/).
21 changes: 21 additions & 0 deletions docs/content/features/deletes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: "Deletes"
weight: 8
description: "Learn how to delete documents from the database using Morphia queries"
---

## Deletes

Queries are used to delete documents from the database as well.
Using
[Query#delete()](/javadoc/dev/morphia/query/Query.html#delete()), we can delete documents matching the query.
The default operation will only delete the first matching document.
However, you can opt to delete all matches by passing in the appropriate options:

```java
datastore
.find(Hotel.class)
.filter(gt("stars", 100))
.delete(new DeleteOptions()
.multi(true));
```
129 changes: 129 additions & 0 deletions docs/content/features/indexing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: "Indexing"
weight: 4
description: "Define and manage indexes for MongoDB collections using Morphia annotations at the class and field level."
---

## 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
[TTL](https://docs.mongodb.com/manual/core/index-ttl/), [text](https://docs.mongodb.com/manual/core/index-text/), and [geospatial](https://docs.mongodb.com/manual/applications/geospatial-indexes/)
indexes.
When defining [text indexes](#text-indexing), there are certain restrictions which will be covered below.
Full details for all these types are available in the [manual](https://docs.mongodb.com/manual/indexes). Morphia will apply any indexes for you at start up by
setting the `morphia.apply-indexes` to true in the [configuration file](/configuration).

There are two ways to define indexes: at the class level and at the field level.

### Class Level Indexes

Class level indexing begins with the [@Indexes](/javadoc/dev/morphia/annotations/Indexes.html) annotation.
This is a container annotation whose sole purpose is to hold a number of [@Index](/javadoc/dev/morphia/annotations/Index.html) annotations.
This annotation has two primary components to cover here: `fields` and `options`.
An index definition would take the following form:

```java
@Entity
@Indexes({
@Index(fields = @Field(value = "field2", type = DESC)),
@Index(
fields = @Field("field3"),
options = @IndexOptions(name = "indexing_test")
)
})
public class IndexExample {
@Id
private ObjectId id;
private String field;
@Property
private String field2;
@Property("f3")
private String field3;
}
```

### Fields

Which fields to index are defined with the [@Field](/javadoc/dev/morphia/annotations/Field.html) annotation.
An arbitrary number of [@Field](/javadoc/dev/morphia/annotations/Field.html)s can be given but at least one must be present.
The name used for the field can be either the Java field name or the mapped document field name as defined in the class's mapping via, e.g., the
[@Property](/javadoc/dev/morphia/annotations/Property.html) or [@Embedded](/javadoc/dev/morphia/annotations/Embedded.html)
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

Options for an index are defined on the [@IndexOptions](/javadoc/dev/morphia/annotations/IndexOptions.html).
More complete documentation can be found in the [manual](https://docs.mongodb.com/manual/reference/method/db.collection.createIndex/#options).
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 [manual](https://docs.mongodb.com/manual/core/index-creation/#background-construction) 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 reference. `IndexOptions` lets you define [TTL](https://docs.mongodb.com/manual/core/index-ttl/), [sparse](https://docs.mongodb.com/manual/core/index-sparse/), and [partial](https://docs.mongodb.com/manual/core/index-partial/) indexes as well. `IndexOptions` can also be used to give an index a more human friendly name.

{{% notice note %}}
Whether user specified or MongoDB generated, index names including their full namespace (i.e. database.collection) cannot be longer than the [Index Name Limit](https://docs.mongodb.com/manual/reference/limits/#Index-Name-Length).
{{% /notice %}}

#### Partial Indexes

New in MongoDB 3.2, [partial indexes](https://docs.mongodb.com/v3.2/core/index-partial/) 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:

```java
@Indexes({@Index(options =
@IndexOptions(partialFilter = "{ name : { $exists : true } }"),
fields = {@Field(value = "name")})})
public class SomeClass {
...
}
```

## Field Level Indexes

Field level indexing is a simpler approach to defining a basic, single key index.
These indexes are defined by applying the
[@Indexed](/javadoc/dev/morphia/annotations/Indexed.html) annotation to a particular field on a class.
Because the index definition is applied at the field level, the index is created using only that field and so the [@Field](/javadoc/dev/morphia/annotations/Field.html)
annotations are unnecessary.
The options for the index are the same as defined [above](#index-options).
A field level index definition would look like this:

```java
@Entity
private class FieldIndex {
@Id
private ObjectId id;
@Indexed(options = @IndexOptions(unique = true))
private String name;
private String color;
}
```

## Text Indexing {#text-indexing}

Morphia's indexing supports MongoDB's text indexing and search functionality as we've briefly seen above.
Full details can be found in the [manual](https://docs.mongodb.com/manual/core/index-text/) but there are a few Morphia specific details to cover.
Indexed field names are validated by default but validation is disabled when an index is defined using MongoDB's
[$**](https://docs.mongodb.com/manual/core/index-text/#text-index-wildcard) syntax.
This special instruction tells MongoDB to create a text index on all fields with string content in a document.
A [compound index](https://docs.mongodb.com/manual/core/index-text/#compound-index) can be created incorporating a text index but it's important to note there can only be one text index on a collection.

A wild card text index declaration would look like this:

```java
@Indexes(@Index(fields = @Field(value = "$**", type = TEXT)))
```

{{% notice note %}}
A collection can have at most one text index.
{{% /notice %}}

### 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 [@IndexOptions](/javadoc/dev/morphia/annotations/IndexOptions.html)
and takes a [@Collation](/javadoc/dev/morphia/annotations/Collation.html) instance.
42 changes: 42 additions & 0 deletions docs/content/features/kotlin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: "Kotlin"
weight: 2
description: "Using Morphia with Kotlin including support for delegated properties"
---

## 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.
Morphia 2.2 introduces a new module dependency for those who need that extra support.
To import the new
`morphia-kotlin` module in maven, simply add this to your `pom.xml`:

```xml
<dependencies>
<dependency>
<groupId>dev.morphia.morphia</groupId>
<artifactId>morphia-kotlin</artifactId>
<version>{version}</version>
</dependency>
</dependencies>
```

And, of course, gradle users can use the following dependency declaration:

```groovy
dependencies {
compile 'dev.morphia.morphia:morphia-kotlin:{version}'
}
```

Explicit Kotlin support is relatively new so there are likely cases that haven't been discovered yet that might still need specific help but this new module will help cover those cases going forward.

New to 2.2 is support for [delegated properties](https://kotlinlang.org/docs/delegated-properties.html).
If your project uses
`Delegates.notNull()`, e.g., you will want to include this module to support that delegation.
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 [issue](/issues-help).
Loading