Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Commit

Permalink
merge: Migrate the documentation to MkDocs
Browse files Browse the repository at this point in the history
  • Loading branch information
CLOVIS-AI authored Jul 13, 2024
2 parents 02b7e2c + 1a4a80a commit 2c24601
Show file tree
Hide file tree
Showing 23 changed files with 596 additions and 57 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/CI.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: CI

# Run this workflow every time a new commit pushed to your repository
on: push

jobs:
build-and-test:
name: Build and test
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build
run: ./gradlew build

- name: Upload Unit Test Results
if: always()
uses: actions/upload-artifact@v2
with:
name: tests-results # Name artifact for storage in cache
path: |
**/build/test-results/**/*.xml
publish-test-results:
name: Publish tests results
runs-on: ubuntu-latest
needs: build-and-test
# the build-and-test job might be skipped, we don't need to run this job then
if: success() || failure()
permissions:
checks: write
pull-requests: write

steps:
- name: Download Artifacts
uses: actions/download-artifact@v2
with:
name: tests-results # Name of artifact in cache
path: tests-results/

- name: Publish Unit Test Results
uses: docker://ghcr.io/enricomi/publish-unit-test-result-action:v1
if: always()
with:
github_token: ${{ github.token }}
files: tests-results/**/*.xml
45 changes: 45 additions & 0 deletions .github/workflows/Website.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Website

on: push

jobs:
mkdocs:
name: Generate the MkDocs website
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2
- uses: actions/setup-python@v5
with:
python-version: 3.x
- name: Install MkDocs
run: pip install mkdocs-material[imaging]
- name: Generate the website
run: |
pushd docs/website
mkdocs build --site-dir ../../docs-website
popd
ls
- uses: actions/upload-pages-artifact@v3
with:
path: docs-website

deploy:
needs: mkdocs

if: success() && github.ref == 'refs/heads/main'

permissions:
pages: write
id-token: write

environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
31 changes: 31 additions & 0 deletions .idea/runConfigurations/Documentation_website.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/runConfigurations/Open_documentation_website.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,9 @@ plugins {
alias(libs.plugins.kotlin) apply false
alias(libs.plugins.dokkatoo)
}

dependencies {
dokkatoo(projects.dsl)
dokkatoo(projects.driverSync)
dokkatoo(projects.driverCoroutines)
}
20 changes: 4 additions & 16 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,13 @@

To learn what KtMongo is and why it exists, see the [root README](../README.md).

To learn about specific KtMongo features, functions or operators, see the Reference.
## The website

## Getting started
The KtMongo website contains guides to get started with KtMongo, guides to migrate from KMongo to KtMongo, and the generated API reference.

To learn how to use KtMongo in your project and to learn about new MongoDB features.
Its sources are available in the [website/](website) directory.

- Adding KtMongo to your project
- [Connecting and configuring a database](guides/connect.md)
- Saving data
- [Searching for data](guides/search.md)
- Referencing nested fields

## How to migrate from KMongo?

List of differences between KMongo and KtMongo to help you migrate your existing projects.

- Using KMongo and KtMongo together
- [Referencing nested fields](migrate-from-kmongo/nested-fields.md)
- [The operator DSL](migrate-from-kmongo/dsl.md)
To build it locally, run the `Open documentation website` run configuration.

## Design documents

Expand Down
1 change: 1 addition & 0 deletions docs/website/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.cache
67 changes: 67 additions & 0 deletions docs/website/docs/guides/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Features overview

This page describes the improvements brought by KtMongo over the official drivers.
If you're interested in a comparison with KMongo, see [the dedicated page](../migrate-from-kmongo/why.md).

## Query DSL and optional filters

A typical scenario is to filter data based on criteria passed by the user. In this example, we'll be searching for users of a given last name, with an optional minimum age filter.

First, let's declare our classes to represent the data we're working with. The drivers will automatically deserialize documents to these classes.

```kotlin
class User(
val _id: String,
val name: UserName,
val age: Int,
)

class UserName(
val firstName: String,
val lastName: String,
)
```

Let's implement this request with the official drivers.

```java title="With the official Java driver"
Bson filter = eq("name.lastName", lastName);

if(minAge !=null)
filter =

and(filter, gt("age", minAge));

users.

find(filter);
```

The official drivers use the builder pattern. In this example, reference mutability is used to incrementally create the filter.

This example is hard to maintain:

- Field names, and their hierarchy, are passed as strings: when refactoring code, requests risk being outdated.
- Filters are of the type `Bson`: the type doesn't help us verify that the request actually applies to the contents of the collection. If we accidentally use a function made for another collection, its filters may apply in different ways or not apply at all if the field names are different.
- There are no type checks: we could try to compare the `name` field with a `String`, which would give no results since it is a child document.
- The structure of the request is not immediately visible at a glance, due to being spread over the condition.

Now, let's rewrite this example with KtMongo:

```kotlin title="With KtMongo"
users.find {
User::name / UserName::lastName eq lastName
User::age gtNotNull minAge
}
```

A few improvements have been made to simplify the request:

- Referring to fields is done by writing a reference to the actual fields, meaning we can find all requests using a field by clicking on it in our IDE.
- Refactoring fields will correctly update all requests using them.
- Operator arguments are type-checked, so we cannot compare a field with an incompatible type.
- The structure of the request is immediately visible, and the `$and` operator is implied by the presence of multiple arguments.
- The `gtNotNull` operator handles the optional filter for us.
- Only filters that apply to the collection being searched in can be specified in the `find` block, we cannot accidentally use filters meant for another collection.

These various improvements make the final request much easier to read and understand at a glance.
12 changes: 7 additions & 5 deletions docs/guides/search.md → docs/website/docs/guides/search.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Searching the database
# Find data

In this document, we will see how to search for specific data in the database.

> Pre-requisites:
> - [Obtain a collection](connect.md)
!!! note ""
Before retrieving data, you must [connect to the database and obtain a collection](setup.md).

Let's assume we have the following class:

```kotlin
class User(
val name: String,
Expand All @@ -14,13 +13,15 @@ class User(
```

To return all documents in a collection, we can use `find`:

```kotlin
collection.find()
.toList()
.forEach { println(" - $it") }
```

To only return specific documents, we can add a filter expression:

```kotlin
// Find all users who have a name and who are older than 18
collection.find {
Expand All @@ -31,6 +32,7 @@ collection.find {
```

If we know that only one user may exist, we can use `findOne` instead:

```kotlin
collection.findOne { User::name eq "Sylvain De La Fontaine" }
```
14 changes: 12 additions & 2 deletions docs/guides/connect.md → docs/website/docs/guides/setup.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# Interacting with a database
# Quick start

This article describes how to connect to a MongoDB instance, how to access a specific collection, and how to perform a simple request.
## Choose between suspension and blocking

## Add the dependency

[//]: # (TODO: publish to central)

KtMongo is currently not published to MavenCentral. To import it into your projects, use a [Gradle composite build](https://docs.gradle.org/current/userguide/composite_builds.html).

## Connect to a database

First, instantiate a client and request a specific database:

```kotlin
val database = MongoClient.create("mongodb://localhost:PORT-NUMBER")
.getDatabase("foo")
Expand All @@ -15,6 +22,7 @@ To configure more options, see [the official documentation](https://www.mongodb.
## Access a collection

First, create a class that represents the documents stored in the collection:

```kotlin
class User(
val name: String,
Expand All @@ -23,6 +31,7 @@ class User(
```

Now, instantiate the collection:

```kotlin
val collection = database.getCollection<User>("users")
.asKtMongo()
Expand All @@ -31,6 +40,7 @@ val collection = database.getCollection<User>("users")
## Perform a simple operation

Now that we have access to the collection, we can perform operations on it:

```kotlin
val count = collection.countDocumentsEstimated()
```
43 changes: 43 additions & 0 deletions docs/website/docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
template: home.html
---

# Towards the future of MongoDB in Kotlin

In 2016, Julien Buret created [KMongo](https://github.com/Litote/kmongo), a Kotlin driver for MongoDB based on the official Java driver. KMongo added a lot of syntax sugar, making complex queries much more readable and less error-prone thanks to improved type safety:

```java
// Official Java driver
Bson filter = and(eq("user.gender", "female"), gt("user.age", 29));
collection.

find(filter);
```

```kotlin
// KMongo
collection.find(
and(
Document::user / User::gender eq "female",
Document::user / User::age gt 29
)
)
```

In 2023, MongoDB released an official Kotlin driver. Development of KMongo stopped, but the official driver lacked much of the syntax niceties of KMongo, as well as requiring major migration efforts. As a result, many projects decided to keep using KMongo for the foreseeable future.

We decided to take it upon ourselves to birth the future of MongoDB drivers for Kotlin. KtMongo is based on the official Kotlin driver to ensure we profit from security fixes and new features, and reimplements a DSL inspired by KMongo.

This project is for **everyone who works with KMongo and is worried about the future after the deprecation notice**, as well as for **everyone dissatisfied with the official Kotlin driver**.

If you're starting a new project, or are using the official Java or Kotlin drivers, [discover what we can do for you](guides/overview.md).

## Why not just fork KMongo?

Since KMongo was started, MongoDB and Kotlin have changed a lot. Aggregation pipelines have become an important tool, type-safety has become more critical. We believe some breaking changes are necessary to bring KMongo into the next decades.

We intend KtMongo to be the spiritual successor to KMongo, making changes where insight has given us new ideas. We intend to facilitate gradual migration from KMongo to KtMongo such that projects can profit from these new features and official MongoDB support at their own pace.

To achieve these objectives, KMongo and KtMongo are mutually compatible: they can both be used in a single project. However, KMongo is based on the Java driver, and KtMongo is based on the Kotlin driver, so many classes are slightly different. We recommend adding both libraries together during the migration phase, and migrating files one at a time at your own rhythm, much like when migrating from Java to Kotlin.

To learn more about the changes we have made, see [the KMongo migration guide](migrate-from-kmongo/why.md).
Loading

0 comments on commit 2c24601

Please sign in to comment.