MongoDB基礎：JAVAでCRUDから入門

#はじめに
MongoDBは、NoSQLの世界ではドキュメント型の代表者であり、CRUDの実装は簡単です。
JAVAでCRUDのAPIを利用して簡単にまとめます。

#ドライバライブラリ導入
```build.gradle
// https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver
compileInclude group: 'org.mongodb', name: 'mongo-java-driver', version: '3.11.0'
```

#Create
##インサートイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/c419f2fc-690e-f55e-a097-fe1465f3b076.png)


##JAVAインサートサンプル
```MongoDBTest.java
package mongodb;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

import org.bson.Document;

public class MongoDBTest {

	public static void main(String[] args) {
		// MongoDBクライントを生成する
		MongoClient client = MongoClients.create("mongodb://localhost:27017");
		// DBオブジェクトを取得する
		MongoDatabase db = client.getDatabase("mydb");
		// ユーザーコレクションを取得する
		MongoCollection<Document> users = db.getCollection("users");

		// ユーザーの属性をセット
		Document user = new Document();
		user.append("lastName", "tanaka");
		user.append("firstName", "ichiro");
		user.append("gender", "男性");

		// DBにインサート
		users.insertOne(user);

		// クライントを閉じる
		client.close();
	}
}

```


##コレクションイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/2e3c9e0b-2916-d2a1-7159-879482611c21.png)


## 複数インサート
```java
List<Document> userList = new ArrayList<Document>();
		
Document user1 = new Document();
user1.append("lastName", "tanaka");
		
Document user2 = new Document();
user2.append("lastName", "yamada");
		
userList.add(user1);
userList.add(user2);
		
// リストをDBにインサート
users.insertMany(userList);
```
#Read
##検索イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/5d5f0e17-33e6-b335-0b13-be8f1cf915d0.png)

##Find One
db.collection.find(filter).first()の感じで一件目を取得する。_idで検索したい場合はfirstメソッドが便利です。

```MongoDBTest.java
package mongodb;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.Filters;

import org.bson.Document;
import org.bson.types.ObjectId;

public class MongoDBTest {

	public static void main(String[] args) {
		// MongoDBクライントを生成する
		MongoClient client = MongoClients.create("mongodb://localhost:27017");
		// DBオブジェクトを取得する
		MongoDatabase db = client.getDatabase("mydb");
		// ユーザーコレクションを取得する
		MongoCollection<Document> users = db.getCollection("users");

		// _idで検索する
		Document user = users.find(Filters.eq("_id", new ObjectId("5d858b36c491de05900c4e32"))).first();
		if (user != null) {
			System.out.println("lastName:" + user.getString("lastName"));
		}

		// クライントを閉じる
		client.close();
	}
}

```
出力：
>lastName:tanaka

##Find List
findメソッドのパラメータに検索条件を渡すと絞り込むことは可能です。
Filtersクラスではいろんなメソッドを用意されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/15998b2f-9cf6-0866-b19d-c778d0eb8c80.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/ddf27d06-6dff-b81b-79d3-506e143e485a.png)


###検索サンプル

```java
// 姓で複数人を検索する
MongoCursor<Document> cursor = users.find(Filters.or(Filters.in("lastName", "tanaka", "yamada"))).cursor();
while (cursor.hasNext()) {
    Document user = (Document) cursor.next();
    // do something
}

// Cursorではなく、リストに変換しても便利です。
// List<Document> documents = users.find(Filters.or(Filters.in("lastName", "tanaka", "yamada"))).into(new ArrayList<Document>());

```

###　ソート、skip,limitなど
```java
Document sort = new Document();
sort.append("updateDate", -1);
MongoCursor<Document> cursor = users.find(Filters.in("lastName", "tanaka", "yamada")).sort(sort).skip(20).limit(10).cursor();
```

#Update
## 更新イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/cbce4dc2-9770-35b6-0110-5c3c8d401a9f.png)

##Update One

## updateOneメソッドで１件のデータを更新

```MongoDBTest.java
package mongodb;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

import java.util.Date;

import org.bson.Document;
import org.bson.types.ObjectId;

public class MongoDBTest {

	public static void main(String[] args) {
		// MongoDBクライントを生成する
		MongoClient client = MongoClients.create("mongodb://localhost:27017");
		// DBオブジェクトを取得する
		MongoDatabase db = client.getDatabase("mydb");
		// ユーザーコレクションを取得する
		MongoCollection<Document> users = db.getCollection("users");
		
		// 更新条件
		Document filter = new Document();
		filter.append("_id", new ObjectId("5d858b36c491de05900c4e32"));
		
		// 更新データ
		Document updateSet = new Document();
		updateSet.append("lastName", "鈴木");
		updateSet.append("updateDate", new Date());
		
		// updateオブジェクト
		Document update = new Document();
		update.append("$set", updateSet);
		
		// 更新
		users.updateOne(filter , update);
		
		// クライントを閉じる
		client.close();
	}
}

```

###更新後のコレクションのデータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/13cd5426-54bc-f994-b336-4865a133a0a3.png)


##Update Many
条件と一致するデータを更新したい場合はupdateManyメソッドを使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/f20808e6-404f-49e7-95c4-74f9a32a1d9a.png)

更新のマニュアル：https://docs.mongodb.com/manual/tutorial/update-documents/

##Replace One
ドキュメントを一部データ更新ではなく、完全差し替えの場合は、replaceOneメソッドを使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/cfbb5ffd-5b85-45f5-c7b4-148c27dc9fc2.png)

```java
// 更新条件
Document filter = new Document();
filter.append("_id", new ObjectId("5d858b36c491de05900c4e32"));
		
// 更新データ
Document update = new Document();
update.append("lastName", "鈴木");
update.append("updateDate", new Date());
		
// 差し替え
users.replaceOne(filter, update);
```

一点注意したいのは、DBで検索したドキュメントを差し替えデータとして処理すると、エラーになります。
悪い例：

```java
// DBからデータ取得
Document user = users.find(Filters.eq("_id", new ObjectId("5d858b36c491de05900c4e32"))).first();
user.append("memo", "new user");
		
// 差し替え(違う_idなので、エラーになる。同じ_idなら問題ありません。)
users.replaceOne(Filters.eq("_id", new ObjectId("5d859c77b64c3286a4d29d90")), user);
```

違う_idの場合は、userの_idフィールドを削除すればエラー解消できます。
Versionデータが有る場合は、replaceOneメソッドを使ってよいかもしれません。

```java
// DBからデータ取得
Document user = users.find(Filters.eq("_id", new ObjectId("5d858b36c491de05900c4e32"))).first();
user.append("memo", "new user");
user.remove("_id");
```


#Delete
## 削除イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/9df7ddd0-be47-8aa5-03fa-b81105f0a3f9.png)

##deleteOne
`users.deleteOne(Filters.eq("_id", new ObjectId("5d859c77b64c3286a4d29d90")));`


##deleteMany
`users.deleteMany(Filters.eq("lastName", "鈴木"));`


##削除関連メソッド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/a7d3d912-9ad9-2367-f086-c4be56913ed7.png)


マニュアル：　https://docs.mongodb.com/manual/
CRUD（本文のイメージ）：　https://docs.mongodb.com/manual/crud/

以上