Skip to content

Commit e7123f2

Browse files
christophstroblodrotbohm
authored andcommitted
spring-projects#297 - Add sample for fluent MongoDB API.
1 parent 7a557bf commit e7123f2

File tree

10 files changed

+578
-1
lines changed

10 files changed

+578
-1
lines changed

mongodb/fluent-api/README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Spring Data MongoDB 2.0 - FluentMongoOperations Example
2+
3+
This project contains usage samples of `FluentMongoOperations`.
4+
5+
## Fluent API
6+
7+
`FluentMongoOperations` provides a stripped down, more focused API alternative for classic `MongoOperations`.
8+
The main entry points are typical tasks for finding and manipulating ``Document``s on a domain type base, while operations like creating indexes are left out.
9+
10+
For convenience classic `MongoOperations` extend `FluentMongoOperations`, however for most cases it might be sufficient to just work with the reduced interface.
11+
To get started just inject `FluentMongoOperations`.
12+
13+
The entry point methods of `FluentMongoOperations` provide you with an immutable fluent API allowing only valid next steps while constructing the operation to execute. This allows to set up operations once and keep those in memory for multiple executions.
14+
15+
### Query
16+
17+
Looking at the following `query(SWCharacter.class)`.
18+
19+
`SWCharacter` is used for mapping the query properties to the actual document field names. As the `SWCharacter` defines `@Field("firstname") name;` the `where` clause of the query is mapped to the MongoDB representation as `{ firstname : "luke" }`.
20+
21+
Using `as(Jedi.class)` switches return type mapping from `SWCharacter` to `Jedi` which allows to map resulting documents to a different type than the one used for query mapping.
22+
23+
So far no actual query execution has been invoked. Calling on of the terminating methods like `one()`, `first()`, `all()`,... triggers the query.
24+
25+
```java
26+
mongoOps.query(SWCharacter.class)
27+
.inCollection("star-wars")
28+
.as(Jedi.class)
29+
.matching(query(where("name").is("luke")))
30+
.one();
31+
32+
```
33+
34+
Different stages in the command essembly process allow to seamlessly switch to different API paths. Using `near` instead of `matching` switches to the path for geo queries requireing the presence of a `NearQuery` while altering the command result type from `List` to `GeoResults` and limiting terminating operations to just `all()`.
35+
36+
```java
37+
38+
NearQuery alderaanWithin3Parsecs = NearQuery.near(-73.9667, 40.78)
39+
.maxDistance(new Distance(3, MILES))
40+
.spherical(true);
41+
42+
GeoResults<Jedi> results = mongoOps.query(SWCharacter.class)
43+
.as(Jedi.class)
44+
.near(alderaanWithin3Parsecs)
45+
.all();
46+
```
47+
48+
49+
### Update
50+
51+
Looking at the following `update(Jedi.class)`.
52+
53+
`Jedi` already defines the `collection` via the `@Document` annotation, so there is no need to explicitly specify a collection name via `inCollection(String)`. The `Jedi` domain type is also used for query and update mapping.
54+
55+
So far no actual query execution has been invoked. Calling on of the terminating methods like `all()`, `upsert()`, `findAndModify()`, etc. triggers the update.
56+
```java
57+
58+
59+
mongoOps.update(Jedi.class)
60+
.matching(query(where("lastname").is("windu")))
61+
.apply(update("name", "mence"))
62+
.upsert();
63+
```

mongodb/fluent-api/pom.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<artifactId>spring-data-mongodb-fluent-api</artifactId>
6+
7+
<name>Spring Data MongoDB - Fluent API Example</name>
8+
9+
<parent>
10+
<groupId>org.springframework.data.examples</groupId>
11+
<artifactId>spring-data-mongodb-examples</artifactId>
12+
<version>1.0.0.BUILD-SNAPSHOT</version>
13+
</parent>
14+
15+
</project>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.fluent;
17+
18+
import lombok.Data;
19+
20+
/**
21+
* @author Christoph Strobl
22+
*/
23+
@Data
24+
class Human {
25+
26+
final String firstname;
27+
final String lastname;
28+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.fluent;
17+
18+
import lombok.EqualsAndHashCode;
19+
import lombok.Getter;
20+
import lombok.ToString;
21+
22+
/**
23+
* @author Christoph Strobl
24+
*/
25+
@Getter
26+
@EqualsAndHashCode(callSuper = true)
27+
@ToString
28+
class Jedi extends SWCharacter {
29+
30+
private final String lastname;
31+
32+
Jedi(String name, String lastname) {
33+
34+
super(name);
35+
this.lastname = lastname;
36+
}
37+
38+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.fluent;
17+
18+
import lombok.Data;
19+
20+
import org.springframework.data.annotation.Id;
21+
import org.springframework.data.geo.Point;
22+
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
23+
24+
/**
25+
* @author Christoph Strobl
26+
*/
27+
@Data
28+
public class Planet {
29+
30+
final @Id String name;
31+
final @GeoSpatialIndexed Point coordinates;
32+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.fluent;
17+
18+
import lombok.EqualsAndHashCode;
19+
import lombok.Getter;
20+
21+
import lombok.Setter;
22+
import org.springframework.data.annotation.Id;
23+
import org.springframework.data.mongodb.core.mapping.Document;
24+
import org.springframework.data.mongodb.core.mapping.Field;
25+
26+
/**
27+
* @author Christoph Strobl
28+
*/
29+
@Document(collection = "star-wars")
30+
@Getter
31+
@Setter
32+
@EqualsAndHashCode(of = "name")
33+
class SWCharacter {
34+
35+
private @Id String id;
36+
private @Field("firstname") String name;
37+
private Planet homePlanet;
38+
39+
SWCharacter(String name) {
40+
this.name = name;
41+
}
42+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.fluent;
17+
18+
import org.springframework.beans.factory.annotation.Value;
19+
20+
/**
21+
* @author Christoph Strobl
22+
*/
23+
public interface Sith {
24+
25+
@Value("#{target.name + ' ' + target.lastname}")
26+
String getName();
27+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package example.springdata.mongodb.fluent;
17+
18+
import org.springframework.boot.CommandLineRunner;
19+
import org.springframework.boot.autoconfigure.SpringBootApplication;
20+
import org.springframework.context.annotation.Bean;
21+
import org.springframework.data.geo.Point;
22+
import org.springframework.data.mongodb.core.MongoTemplate;
23+
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
24+
import org.springframework.data.mongodb.core.index.GeospatialIndex;
25+
26+
/**
27+
* @author Christoph Strobl
28+
*/
29+
@SpringBootApplication
30+
public class ApplicationConfiguration {
31+
32+
static final String COLLECTION = "star-wars";
33+
34+
@Bean
35+
CommandLineRunner init(MongoTemplate template) {
36+
37+
return (args) -> {
38+
39+
if (template.collectionExists(COLLECTION)) {
40+
template.dropCollection(COLLECTION);
41+
}
42+
43+
GeospatialIndex index = new GeospatialIndex("homePlanet.coordinates") //
44+
.typed(GeoSpatialIndexType.GEO_2DSPHERE) //
45+
.named("planet-coordinate-idx");
46+
47+
template.createCollection(COLLECTION);
48+
template.indexOps(SWCharacter.class).ensureIndex(index);
49+
50+
Planet alderaan = new Planet("alderaan", new Point(-73.9667, 40.78));
51+
Planet stewjon = new Planet("stewjon", new Point(-73.9836, 40.7538));
52+
Planet tatooine = new Planet("tatooine", new Point(-73.9928, 40.7193));
53+
54+
Jedi anakin = new Jedi("anakin", "skywalker");
55+
anakin.setHomePlanet(tatooine);
56+
57+
Jedi luke = new Jedi("luke", "skywalker");
58+
luke.setHomePlanet(tatooine);
59+
60+
Jedi leia = new Jedi("leia", "organa");
61+
leia.setHomePlanet(alderaan);
62+
63+
Jedi obiWan = new Jedi("obi-wan", "kenobi");
64+
obiWan.setHomePlanet(stewjon);
65+
66+
Human han = new Human("han", "solo");
67+
68+
template.save(anakin, COLLECTION);
69+
template.save(luke, COLLECTION);
70+
template.save(leia, COLLECTION);
71+
template.save(obiWan, COLLECTION);
72+
template.save(han, COLLECTION);
73+
};
74+
}
75+
}

0 commit comments

Comments
 (0)