1. 概要

このチュートリアルでは、実際の例とともに、クラスのMongoDBコレクション名を構成する方法を学習します。 Spring Data を使用します。これにより、わずかな構成でこれを実現するためのいくつかのオプションが提供されます。 簡単な音楽店を建てて、それぞれのオプションを検討します。 そうすれば、いつそれらを使用するのが理にかなっているのかを知ることができます。

2. ユースケースとセットアップ

このユースケースには、 MusicAlbum Compilation MusicTrack 、およびStoreの4つの単純なクラスがあります。 各クラスのコレクション名は異なる方法で構成されます。また、各クラスには独自のMongoRepositoryがあります。 カスタムクエリは必要ありません。 さらに、MongoDBデータベースの適切に構成されたインスタンスが必要になります。

2.1. コレクションの内容を名前で一覧表示するサービス

まず、構成が機能していることを表明するコントローラーを作成しましょう。 コレクション名で検索して行います。 リポジトリを使用する場合、コレクション名の構成は透過的であることに注意してください。

@RestController
@RequestMapping("/collection")
public class CollectionController {
    @Autowired
    private MongoTemplate mongoDb;

    @GetMapping("/{name}")
    public List<DBObject> get(@PathVariable String name) {
        return mongoDb.findAll(DBObject.class, name);
    }
}

このコントローラーはMongoTemplateに基づいており、クラスやリポジトリーに依存しないジェネリック型DBObjectを使用します。 また、このようにして、MongoDBの内部プロパティを確認できます。 最も重要なのは、Spring DataがJSONオブジェクトをアンマーシャリングするために使用する「_class」プロパティが、構成が正しいことを保証することです。

2.2. APIサービス

次に、オブジェクトを保存してコレクションを取得するだけのサービスの構築を開始します。 Compilationクラスは後で最初の構成例で作成されます。

@Service
public class MusicStoreService {
    @Autowired
    private CompilationRepository compilationRepository;

    public Compilation add(Compilation item) {
        return compilationRepository.save(item);
    }

    public List<Compilation> getCompilationList() {
        return compilationRepository.findAll();
    }

    // other service methods
}

2.3. APIエンドポイント

最後に、アプリケーションとインターフェイスするコントローラーを作成しましょう。 サービスメソッドのエンドポイントを公開します。

@RestController
@RequestMapping("/music")
public class MusicStoreController {
    @Autowired
    private MusicStoreService service;

    @PostMapping("/compilation")
    public Compilation post(@RequestBody Compilation item) {
        return service.add(item);
    }

    @GetMapping("/compilation")
    public List<Compilation> getCompilationList() {
        return service.getCompilationList();
    }

    // other endpoint methods
}

その後、クラスの構成を開始する準備が整いました。

3. @Documentアノテーションを使用した構成

Spring Dataバージョン1.9以降で利用可能なDocumentアノテーションは、必要なすべてを実行します。 これはMongoDBに固有ですが、JPAのEntityアノテーションに似ています。 この記事の執筆時点では、コレクション名の命名戦略を定義する方法はなく、フィールド名のみです。したがって、利用可能なものを調べてみましょう。

3.1. デフォルトの動作

デフォルトの動作では、コレクション名はクラス名と同じであると見なされますが、小文字で始まります。 要するに、ドキュメント注釈を追加するだけで、機能します

@Document
public class Compilation {
    @Id
    private String id;

    // getters and setters
}

その後、 Compilation リポジトリからのすべての挿入は、MongoDBの「compilation」という名前のコレクションに入れられます。

$ curl -X POST http://localhost:8080/music/compilation -H 'Content-Type: application/json' -d '{
    "name": "Spring Hits"
}'

{ "id": "6272e26e04a673360d926ca1" }

構成を確認するために、「コンパイル」コレクションの内容をリストしてみましょう。

$ curl http://localhost:8080/collection/compilation

[
  {
    "name": "Spring Hits",
    "_class": "com.baeldung.boot.collection.name.data.Compilation"
  }
]

これは、基本的にクラス名と同じであるため、コレクション名を構成するための最もクリーンな方法です。 1つの欠点は、データベースの命名規則を変更する場合、すべてのクラスをリファクタリングする必要があることです。たとえば、コレクション名にスネークケースを使用する場合、変更しません。デフォルトの動作を利用できるようになります。

3.2. valueプロパティのオーバーライド

Document アノテーションを使用すると、collectionプロパティを使用してデフォルトの動作をオーバーライドできます。 このプロパティはvalueプロパティのエイリアスであるため、暗黙的に設定できます。

@Document("albums")
public class MusicAlbum {
    @Id
    private String id;

    private String name;

    private String artist;

    // getters and setters
}

これで、ドキュメントが「musicAlbum」という名前のコレクションに入る代わりに、「albums」コレクションに入るようになります。 これは、Spring Dataを使用してコレクション名を構成する最も簡単な方法です。 実際の動作を確認するために、コレクションにアルバムを追加しましょう。

$ curl -X POST 'http://localhost:8080/music/album' -H 'Content-Type: application/json' -d '{
  "name": "Album 1",
  "artist": "Artist A"
}'

{ "id": "62740de003d2452a61a75c35" }

次に、「アルバム」コレクションをフェッチして、構成が機能することを確認します。

$ curl 'http://localhost:8080/collection/albums'

[
  {
    "name": "Album 1",
    "artist": "Artist A",
    "_class": "com.baeldung.boot.collection.name.data.MusicAlbum"
  }
]

また、クラスと一致しないコレクション名を使用して、アプリケーションを既存のデータベースに適合させるのにも最適です。 1つの欠点は、デフォルトのプレフィックスを追加する必要がある場合、すべてのクラスに対してそれを行う必要があることです。

3.3. SpELでの構成プロパティの使用

この組み合わせは、ドキュメント注釈だけでは不可能なことを行うのに役立ちます。 クラス間で再利用したいアプリケーション固有のプロパティから始めます。

まず、コレクション名のサフィックスとして使用するプロパティをapplication.propertiesに追加しましょう

collection.suffix=db

それでは、 environment beanを介してSpELで参照し、次のクラスを作成しましょう。

@Document("store-#{@environment.getProperty('collection.suffix')}")
public class Store {
    @Id
    private String id;

    private String name;

    // getters and setters
}

次に、最初のストアを作成しましょう。

$ curl -X POST 'http://localhost:8080/music/store' -H 'Content-Type: application/json' -d '{
  "name": "Store A"
}'

{ "id": "62744c6267d3a034ec5e5719" }

その結果、クラスは「store-db」という名前のコレクションに格納されます。 ここでも、内容を一覧表示することで構成を確認できます。

$ curl 'http://localhost:8080/collection/store-db'

[
  {
    "name": "Store A",
    "_class": "com.baeldung.boot.collection.name.data.Store"
  }
]

そうすれば、接尾辞を変更しても、すべてのクラスで手動で変更する必要はありません。 代わりに、プロパティファイルを更新するだけです。 欠点は、それがより定型的であり、とにかくクラス名を書かなければならないことです。 ただし、マルチテナンシーサポートにも役立ちます。 たとえば、サフィックスの代わりに、共有されていないコレクションをマークするためのテナントIDを使用できます。

3.4. SpELでBeanメソッドを使用する

SpELを使用するもう1つの欠点は、プログラムで評価するために追加の作業が必要になることです。 ただし、beanメソッドを呼び出してコレクション名を決定するなど、多くの可能性が開かれます。 したがって、次の例では、 beanを作成して、名前付け規則に準拠するようにコレクション名を修正します。

命名戦略では、スネークケースを使用します。 まず、Spring Dataの SnakeCaseFieldNamingStrategy からコードを借りて、ユーティリティbeanを作成しましょう。

public class Naming {
    public String convert(String name) {
        List<String> parts = ParsingUtils.splitCamelCaseToLower(name);
        List<String> result = new ArrayList<>();

        for (String part : parts) {
            if (StringUtils.hasText(part)) {
                result.add(part);
            }
        }

        return StringUtils.collectionToDelimitedString(result, "_");
    }
}

次に、そのbeanをアプリケーションに追加しましょう。

@SpringBootApplication
public class SpringBootCollectionNameApplication {
    
    // main method

    @Bean
    public Naming naming() {
        return new Naming();
    }
}

その後、SpELを介してbeanを参照できるようになります。

@Document("#{@naming.fix('MusicTrack')}")
public class MusicTrack {
    @Id
    private String id;

    private String name;

    private String artist;

    // getters and setters
}

コレクションにアイテムを追加して試してみましょう。

$ curl -X POST 'http://localhost:8080/music/track' -H 'Content-Type: application/json' -d '{
  "name": "Track 1",
  "artist":"Artist A"
}'

{ "id": "62755987ae94c5278b9530cc" }

したがって、トラックは「music_track」という名前のコレクションに保存されます。

$ curl 'http://localhost:8080/collection/music_track'

[
  {
    "name": "Track 1",
    "artist": "Artist A",
    "_class": "com.baeldung.boot.collection.name.data.MusicTrack"
  }
]

残念ながら、クラス名を動的に取得する方法はありません。これは大きな欠点ですが、すべてのクラスの名前を手動で変更しなくても、データベースの命名規則を変更できます。

4. 結論

この記事では、Spring Dataが提供するツールを使用してコレクション名を構成する方法について説明しました。 さらに、それぞれの長所と短所を確認したので、特定のシナリオに最適なものを決定できます。その間に、さまざまなアプローチを紹介する簡単なユースケースを作成しました。

そしていつものように、ソースコードはGitHub利用できます。