Skip to content

Commit

Permalink
fix: doc & small improvements to the code
Browse files Browse the repository at this point in the history
  • Loading branch information
loicmathieu committed Aug 26, 2019
1 parent a1a56b2 commit 67317cf
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 28 deletions.
42 changes: 25 additions & 17 deletions docs/src/main/asciidoc/mongodb-panache-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ include::./attributes.adoc[]

MongoDB is a well known NoSQL Database that is widely used, but using it's raw API can be cumberson as you need to express your entities and your queries in MongoDB Document.

MongoDB with Panache will provides active record style entities (and repositories) like you have in Hibernate ORM with Panache and focuses on making your entities trivial and fun to write in Quarkus.
MongoDB with Panache provides active record style entities (and repositories) like you have in Hibernate ORM with Panache and focuses on making your entities trivial and fun to write in Quarkus.

== First: an example

Expand Down Expand Up @@ -40,7 +40,9 @@ public class Person extends PanacheMongoEntity {
You have noticed how much more compact and readable the code is?
Does this look interesting? Read on!

NOTE: the `list()` method might be surprising at first. It takes fragments of PancheQL queries (subset of JPQL) and contextualize the rest. That makes for very concise but yet readable code. Native MongoDB queries are also supported.
NOTE: the `list()` method might be surprising at first. It takes fragments of PanacheQL queries (subset of JPQL) and contextualize the rest.
That makes for very concise but yet readable code.
MongoDB native queries are also supported.

== Solution

Expand All @@ -65,7 +67,7 @@ mvn io.quarkus:quarkus-maven-plugin:{quarkus-version}:create \
-Dextensions="resteasy-jsonb,mongodb-panache"
----

This command generates a Maven structure importing the RESTEasy/JAX-RS, JSON-B and MongoDB Panache extensions.
This command generates a Maven structure importing the RESTEasy/JAX-RS, JSON-B and MongoDB with Panache extensions.
After this, the quarkus-mongodb-panache extension has been added to your `pom.xml`.

If you don't want to generate a new project you can add the dependency in your `pom.xml`:
Expand Down Expand Up @@ -100,7 +102,7 @@ quarkus.mongodb.connection-string = mongodb://mongo1:27017,mongo2:27017
quarkus.mongodb.database = person
--

The `quarkus.mongodb.databas` property will be used by MongoDB Panache to detemine the name of the database where your entities will be persisted.
The `quarkus.mongodb.database` property will be used by MongoDB with Panache to determine the name of the database where your entities will be persisted.

== Defining your entity

Expand All @@ -121,7 +123,7 @@ NOTE: annotating with `@MongoEntity` is optional, it allows to configure the nam

MongoDB with Panache uses the link:https://mongodb.github.io/mongo-java-driver/3.10/bson/pojos/[PojoCodecProvider] to map your entities to MongoDB Document.

You will be allow to use the following annotations to customize this mapping:
You will be allowed to use the following annotations to customize this mapping:

- `@BsonId`: customize the id field, by default it's the `id` field with a `ObjectId` type.
- `@BsonProperty`: customize the serialized name of the field.
Expand Down Expand Up @@ -245,7 +247,7 @@ The `PanacheQuery` type has many other methods to deal with paging and returning

== Sorting

All methods accepting a query string also an optional `Sort` parameter, which allows your to abstract your sorting:
All methods accepting a query string also accept an optional `Sort` parameter, which allows your to abstract your sorting:

[source,java]
--
Expand Down Expand Up @@ -287,9 +289,10 @@ public class Person extends PanacheMongoEntity {

== Simplified queries

Normally, MongoDB queries are of this form: `{'firstname': 'John', 'lastname':'Doe'}`, this is what we called native MongoDB queries.
Normally, MongoDB queries are of this form: `{'firstname': 'John', 'lastname':'Doe'}`, this is what we called MongoDB native queries.

You can use them if you want, but we also support what we called **PanacheQL** that can be seen as a subset of JP-QL (or HQL) and allow to easily express a query. MongoDB Panache will then map it to native MongoDB query.
You can use them if you want, but we also support what we call **PanacheQL** that can be seen as a subset of JP-QL (or HQL) and allow to easily express a query.
MongoDB with Panache will then map it to MongoDB native query.

If your query does not start with `{`, we will imply PanacheQL query

Expand All @@ -303,13 +306,13 @@ Here are some query examples:
- `lastname like ?1` will be mapped to `{'lastname': {'$regex': ?1}}`. Be careful that this will be link:https://docs.mongodb.com/manual/reference/operator/query/regex/#op._S_regex[MongoDB regex] support and not SQL like pattern.
- `lastname is not null` will be mapped to `{'lastname':{'$exists': true}}`

We will also handle some basic Date type transofmation: all fields of type `Date`, `LocalDate` or `LocalDateTime` will be mapped to MongoDB `ISODate` type.
We also handle some basic Date type transofmation: all fields of type `Date`, `LocalDate` or `LocalDateTime` will be mapped to MongoDB `ISODate` type.

MongoDB Panache also support extented MongoDB queries by providing a `Document` query, this is supported by the find/list/stream/cout/delete methods.
MongoDB with Panache also supports extented MongoDB queries by providing a `Document` query, this is supported by the find/list/stream/cout/delete methods.

== Query parameters

You can pass query parameters, for both native and PanacheQL queries, by index (1-based):
You can pass query parameters, for both native and PanacheQL queries, by index (1-based) as shown below:

[source,java]
--
Expand Down Expand Up @@ -346,7 +349,7 @@ Every query operation accepts passing parameters by index (`Object...`), or by n
== Query projection

Query projection can be done with the `project()` method on the PanacheQuery object that is returned by the `find()` method.
You can use it to restrict witch fields will be returned by the database. Note that the `_id` field will always be returned.
You can use it to restrict which fields will be returned by the database. Note that the `_id` field will always be returned.

[source,java]
--
Expand Down Expand Up @@ -408,7 +411,8 @@ MongoDB offers ACID transactions since version 4.0. MongoDB with Panache doesn't
== Custom IDs

IDs are often a touchy subject, in MongoDB they are usually auto-generated by the database with an `ObjectId`.
In MongoDB with Panache the ID are defined by a field name `id` of the `org.bson.types.ObjectId` type, but if you want ot customize them, once again we have you covered.
In MongoDB with Panache the ID are defined by a field name `id` of the `org.bson.types.ObjectId` type,
but if you want ot customize them, once again we have you covered.

You can specify your own ID strategy by extending `PanacheMongoEntityBase` instead of `PanacheMongoEntity`. Then
you just declare whatever ID you want as a public field by annotating it by @BsonId:
Expand All @@ -425,7 +429,8 @@ public class Person extends PanacheMongoEntityBase {
}
--

If you're using repositories, then you will want to extend `PanacheMongoRepositoryBase` instead of `PanacheMongoRepository` and specify your ID type as an extra type parameter:
If you're using repositories, then you will want to extend `PanacheMongoRepositoryBase` instead of `PanacheMongoRepository`
and specify your ID type as an extra type parameter:

[source,java]
--
Expand All @@ -438,10 +443,13 @@ public class PersonRepository implements PanacheMongoRepositoryBase<Person,Integ

[NOTE]
====
When using `ObjectId`, MongoDB will automatically provides a value for you, but if you use a custom field type, you need to provides yourself the value.
When using `ObjectId`, MongoDB will automatically provide a value for you, but if you use a custom field type,
you need to provides the value by yourself.
====

`ObjectId` can be difficult to use if you want to expose it's value in your rest service. So we create JsonB provides to serialize/deserialize them as String. These provides are not registered by default so you need to register them with a JAXRS `ContextResolver`:
`ObjectId` can be difficult to use if you want to expose its value in your rest service.
So we create JsonB providers to serialize/deserialize them as String.
These providers are not registered by default so you need to register them with a JAXRS `ContextResolver`:

[source,java]
--
Expand Down Expand Up @@ -498,7 +506,7 @@ That's all there is to it: with Panache, MongoDBhas never looked so trim and nea

== Defining entities in external projects or jars

MongoDB with Panacge relies on compile-time bytecode enhancements to your entities.
MongoDB with Panache relies on compile-time bytecode enhancements to your entities.
If you define your entities in the same project where you build your Quarkus application, everything will work fine.
If the entities come from external projects or jars, you can make sure that your jar is treated like a Quarkus application library by adding an empty `META-INF/beans.xml` file.
This will allow Quarkus to index and enhance your entities as if they were inside the current project.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static void insert(Iterable<?> entities) {
}

if (objects.size() > 0) {
//get the first to get the collection from it
// get the first entity to be able to retrieve the collection with it
Object firstEntity = objects.get(0);
MongoCollection collection = getMongoCollection(firstEntity);
insert(collection, objects);
Expand All @@ -73,7 +73,7 @@ public static void insert(Object firstEntity, Object... entities) {
public static void insert(Stream<?> entities) {
List<Object> objects = entities.collect(Collectors.toList());
if (objects.size() > 0) {
//get the first to get the collection from it
// get the first entity to be able to retrieve the collection with it
Object firstEntity = objects.get(0);
MongoCollection collection = getMongoCollection(firstEntity);
insert(collection, objects);
Expand All @@ -93,7 +93,7 @@ public static void update(Iterable<?> entities) {
}

if (objects.size() > 0) {
//get the first to get the collection from it
// get the first entity to be able to retrieve the collection with it
Object firstEntity = objects.get(0);
MongoCollection collection = getMongoCollection(firstEntity);
update(collection, objects);
Expand All @@ -115,7 +115,7 @@ public static void update(Object firstEntity, Object... entities) {
public static void update(Stream<?> entities) {
List<Object> objects = entities.collect(Collectors.toList());
if (objects.size() > 0) {
//get the first to get the collection from it
// get the first entity to be able to retrieve the collection with it
Object firstEntity = objects.get(0);
MongoCollection collection = getMongoCollection(firstEntity);
update(collection, objects);
Expand All @@ -135,7 +135,7 @@ public static void persist(Iterable<?> entities) {
}

if (objects.size() > 0) {
//get the first to get the collection from it
// get the first entity to be able to retrieve the collection with it
Object firstEntity = objects.get(0);
MongoCollection collection = getMongoCollection(firstEntity);
persist(collection, objects);
Expand All @@ -157,7 +157,7 @@ public static void persist(Object firstEntity, Object... entities) {
public static void persist(Stream<?> entities) {
List<Object> objects = entities.collect(Collectors.toList());
if (objects.size() > 0) {
//get the first to get the collection from it
// get the first entity to be able to retrieve the collection with it
Object firstEntity = objects.get(0);
MongoCollection collection = getMongoCollection(firstEntity);
persist(collection, objects);
Expand All @@ -175,7 +175,7 @@ public static void delete(Object entity) {
public static MongoCollection getMongoCollection(Class<?> entityClass) {
MongoEntity mongoEntity = entityClass.getAnnotation(MongoEntity.class);
MongoDatabase database = getMongoDatabase(mongoEntity);
if (mongoEntity != null && !"".equals(mongoEntity.collection())) {
if (mongoEntity != null && !mongoEntity.collection().isEmpty()) {
return database.getCollection(mongoEntity.collection(), entityClass);
}
return database.getCollection(entityClass.getSimpleName(), entityClass);
Expand All @@ -201,7 +201,7 @@ private static void update(MongoCollection collection, Object entity) {
//we transform the entity as a document first
BsonDocument document = getBsonDocument(collection, entity);

//then we get it's id field and create a new Document with only this one that will be our replace query
//then we get its id field and create a new Document with only this one that will be our replace query
BsonValue id = document.get(ID);
BsonDocument query = new BsonDocument().append(ID, id);
collection.replaceOne(query, entity);
Expand All @@ -217,7 +217,7 @@ private static void persist(MongoCollection collection, Object entity) {
//we transform the entity as a document first
BsonDocument document = getBsonDocument(collection, entity);

//then we get it's id field and create a new Document with only this one that will be our replace query
//then we get its id field and create a new Document with only this one that will be our replace query
BsonValue id = document.get(ID);
if (id == null) {
//insert with autogenerated ID
Expand All @@ -236,7 +236,7 @@ private static void persist(MongoCollection collection, List<Object> entities) {
//we transform the entity as a document first
BsonDocument document = getBsonDocument(collection, entity);

//then we get it's id field and create a new Document with only this one that will be our replace query
//then we get its id field and create a new Document with only this one that will be our replace query
BsonValue id = document.get(ID);
if (id == null) {
//insert with autogenerated ID
Expand Down Expand Up @@ -266,7 +266,7 @@ private static MongoCollection getMongoCollection(Object entity) {

private static MongoDatabase getMongoDatabase(MongoEntity entity) {
MongoClient mongoClient = Arc.container().instance(MongoClient.class).get();
if (entity != null && !"".equals(entity.database())) {
if (entity != null && !entity.database().isEmpty()) {
return mongoClient.getDatabase(entity.database());
}
String databaseName = ConfigProvider.getConfig()
Expand Down

0 comments on commit 67317cf

Please sign in to comment.