sql >> データベース >  >> NoSQL >> MongoDB

SpringDataMongoDBのクエリガイド

    1。概要

    このチュートリアルでは、SpringDataMongoDBでさまざまなタイプのクエリを構築することに焦点を当てます。 。

    クエリを使用したドキュメントのクエリについて見ていきます。 および基準 クラス、自動生成されたクエリメソッド、JSONクエリ、QueryDSL。

    Mavenのセットアップについては、紹介記事をご覧ください。

    2。ドキュメントクエリ

    Spring Dataを使用してMongoDBをクエリする最も一般的な方法の1つは、クエリを使用することです。 および基準 ネイティブ演算子を非常によく反映するクラス。

    2.1。 です

    これは単に平等を使用する基準です。それがどのように機能するか見てみましょう。

    次の例では、 Ericという名前のユーザーを探します 。

    私たちのデータベースを見てみましょう:

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581907"),
            "_class" : "org.baeldung.model.User",
            "name" : "Eric",
            "age" : 45
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 55
        }
    }

    次に、クエリコードを見てみましょう。

    Query query = new Query();
    query.addCriteria(Criteria.where("name").is("Eric"));
    List<User> users = mongoTemplate.find(query, User.class);
    

    予想どおり、このロジックは次を返します。

    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    }

    2.2。 正規表現

    より柔軟で強力なタイプのクエリは正規表現です。これにより、MongoDB $ regexを使用して基準が作成されます。 これは、このフィールドの正規表現に適したすべてのレコードを返します。

    startWithと同様に機能します およびendingWith 操作。

    この例では、名前が Aで始まるすべてのユーザーを検索します。 。

    データベースの状態は次のとおりです。

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581907"),
            "_class" : "org.baeldung.model.User",
            "name" : "Eric",
            "age" : 45
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 33
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581909"),
            "_class" : "org.baeldung.model.User",
            "name" : "Alice",
            "age" : 35
        }
    ]
    

    それでは、クエリを作成しましょう:

    Query query = new Query();
    query.addCriteria(Criteria.where("name").regex("^A"));
    List<User> users = mongoTemplate.find(query,User.class);

    これが実行され、2つのレコードが返されます:

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 33
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581909"),
            "_class" : "org.baeldung.model.User",
            "name" : "Alice",
            "age" : 35
        }
    ]

    もう1つの簡単な例を次に示します。今回は、名前が cで終わるすべてのユーザーを探します。 :

    Query query = new Query();
    query.addCriteria(Criteria.where("name").regex("c$"));
    List<User> users = mongoTemplate.find(query, User.class);
    

    したがって、結果は次のようになります。

    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    }

    2.3。 Lt およびgt

    これらの演算子は、 $ ltを使用して基準を作成します (未満)および $ gt (より大きい)演算子。

    20歳から50歳までのすべてのユーザーを探している簡単な例を見てみましょう。

    データベースは次のとおりです。

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581907"),
            "_class" : "org.baeldung.model.User",
            "name" : "Eric",
            "age" : 45
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 55
        }
    }

    クエリコード:

    Query query = new Query();
    query.addCriteria(Criteria.where("age").lt(50).gt(20));
    List<User> users = mongoTemplate.find(query,User.class);
    

    そして、20歳以上50歳未満のすべてのユーザーの結果:

    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    }

    2.4。並べ替え

    並べ替え 結果の並べ替え順序を指定するために使用されます。

    次の例では、年齢別に昇順で並べ替えられたすべてのユーザーが返されます。

    まず、既存のデータは次のとおりです。

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581907"),
            "_class" : "org.baeldung.model.User",
            "name" : "Eric",
            "age" : 45
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 33
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581909"),
            "_class" : "org.baeldung.model.User",
            "name" : "Alice",
            "age" : 35
        }
    ]
    

    sortを実行した後 :

    Query query = new Query();
    query.with(Sort.by(Sort.Direction.ASC, "age"));
    List<User> users = mongoTemplate.find(query,User.class);
    

    これがクエリの結果で、年齢で適切に並べ替えられています。 :

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 33
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581909"),
            "_class" : "org.baeldung.model.User",
            "name" : "Alice",
            "age" : 35
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581907"),
            "_class" : "org.baeldung.model.User",
            "name" : "Eric",
            "age" : 45
        }
    ]

    2.5。ページング可能

    ページネーションを使用した簡単な例を見てみましょう。

    データベースの状態は次のとおりです。

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581907"),
            "_class" : "org.baeldung.model.User",
            "name" : "Eric",
            "age" : 45
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 33
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581909"),
            "_class" : "org.baeldung.model.User",
            "name" : "Alice",
            "age" : 35
        }
    ]
    

    これがクエリロジックです。サイズ2のページを要求するだけです。

    final Pageable pageableRequest = PageRequest.of(0, 2);
    Query query = new Query();
    query.with(pageableRequest);
    

    そしてその結果、予想通り2つのドキュメント:

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581907"),
            "_class" : "org.baeldung.model.User",
            "name" : "Eric",
            "age" : 45
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 33
        }
    ]

    3。生成されたクエリメソッド

    次に、Spring Dataが通常提供する、より一般的なタイプのクエリ、メソッド名から自動生成されたクエリについて見ていきましょう。

    これらの種類のクエリを活用するために必要なのは、リポジトリインターフェイスでメソッドを宣言することだけです。

    public interface UserRepository 
      extends MongoRepository<User, String>, QueryDslPredicateExecutor<User> {
        ...
    }

    3.1。 FindByX

    findByタイプのクエリを調べることから、簡単に始めましょう。この場合、名前で検索を使用します:

    List<User> findByName(String name);

    前のセクション2.1と同様に、クエリの結果は同じで、指定された名前のすべてのユーザーが検索されます:

    List<User> users = userRepository.findByName("Eric");
    

    3.2。 StartingWith およびendingWith

    セクション2.2では、正規表現について説明しました。 ベースのクエリ。もちろん、最初と最後はそれほど強力ではありませんが、それでも、特に実際に実装する必要がない場合は、非常に便利です。

    操作がどのようになるかの簡単な例を次に示します。

    List<User> findByNameStartingWith(String regexp);
    List<User> findByNameEndingWith(String regexp);

    もちろん、これを実際に使用する例は非常に簡単です。

    List<User> users = userRepository.findByNameStartingWith("A");
    
    List<User> users = userRepository.findByNameEndingWith("c");

    そして、結果はまったく同じです。

    3.3。

    セクション2.3と同様に、これにより、 ageGTの年齢のすべてのユーザーが返されます。 およびageLT:

    List<User> findByAgeBetween(int ageGT, int ageLT);

    メソッドを呼び出すと、まったく同じドキュメントが見つかります:

    List<User> users = userRepository.findByAgeBetween(20, 50);
    

    3.4。 いいね およびOrderBy

    今回は、生成されたクエリに2種類の修飾子を組み合わせた、より高度な例を見てみましょう。

    A、という文字を含む名前を持つすべてのユーザーを探します。 また、結果を年齢順に昇順で並べ替えます。

    List<User> users = userRepository.findByNameLikeOrderByAgeAsc("A");
    

    セクション2.4で使用したデータベースの場合、結果は次のようになります。

    [
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581908"),
            "_class" : "org.baeldung.model.User",
            "name" : "Antony",
            "age" : 33
        },
        {
            "_id" : ObjectId("55c0e5e5511f0a164a581909"),
            "_class" : "org.baeldung.model.User",
            "name" : "Alice",
            "age" : 35
        }
    ]

    4。 JSONクエリメソッド

    メソッド名または条件を使用してクエリを表すことができない場合は、より低いレベルで何かを行うことができます。 @Queryを使用します。 注釈

    このアノテーションを使用すると、生のクエリをMongoJSONクエリ文字列として指定できます。

    4.1。 FindBy

    簡単に始めて、 find byをどのように表現するかを見てみましょう。 メソッドの種類 最初:

    @Query("{ 'name' : ?0 }")
    List<User> findUsersByName(String name);
    

    このメソッドは、ユーザーを名前で返す必要があります。プレースホルダー?0 メソッドの最初のパラメータを参照します。

    List<User> users = userRepository.findUsersByName("Eric");

    4.2。 $ regex

    正規表現によるクエリも確認できます。 もちろん、セクション2.2および3.2と同じ結果が得られます。

    @Query("{ 'name' : { $regex: ?0 } }")
    List<User> findUsersByRegexpName(String regexp);

    使用法もまったく同じです:

    List<User> users = userRepository.findUsersByRegexpName("^A");
    
    List<User> users = userRepository.findUsersByRegexpName("c$");

    4.3。 $ lt および$gt

    それでは、ltと gtを実装しましょう。 クエリ:

    @Query("{ 'age' : { $gt: ?0, $lt: ?1 } }")
    List<User> findUsersByAgeBetween(int ageGT, int ageLT);

    メソッドに2つのパラメーターがあるので、これらの各パラメーターを生のクエリ?0のインデックスで参照しています。 および?1:

    List<User> users = userRepository.findUsersByAgeBetween(20, 50);

    5。 QueryDSLクエリ

    MongoRepository QueryDSLプロジェクトを適切にサポートしているため、ここでもタイプセーフなAPIを活用できます。

    5.1。 Mavenの依存関係

    まず、pomで正しいMaven依存関係が定義されていることを確認しましょう:

    <dependency>
        <groupId>com.mysema.querydsl</groupId>
        <artifactId>querydsl-mongodb</artifactId>
        <version>4.3.1</version>
    </dependency>
    <dependency>
        <groupId>com.mysema.querydsl</groupId>
        <artifactId>querydsl-apt</artifactId>
        <version>4.3.1</version>
    </dependency>

    5.2。Q -クラス

    QueryDSLはクエリの作成にQクラスを使用しましたが、実際には手動で作成したくないため、生成する必要があります どういうわけか。

    これを行うには、apt-maven-pluginを使用します。

    <plugin>    
        <groupId>com.mysema.maven</groupId>
        <artifactId>apt-maven-plugin</artifactId>
        <version>1.1.3</version>
        <executions>
            <execution>
                <goals>
                    <goal>process</goal>
                </goals>
                <configuration>
                    <outputDirectory>target/generated-sources/java</outputDirectory>
                    <processor>
                      org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
                    </processor>
                </configuration>
            </execution>
         </executions>
    </plugin>

    ユーザーを見てみましょう 特に@QueryEntityに焦点を当てたクラス 注釈:

    @QueryEntity 
    @Document
    public class User {
     
        @Id
        private String id;
        private String name;
        private Integer age;
     
        // standard getters and setters
    }

    プロセスを実行した後 Mavenライフサイクルの目標(またはその後のその他の目標)、aptプラグインは新しいクラスを生成します target /generated-sources / java/{パッケージ構造}

    /**
     * QUser is a Querydsl query type for User
     */
    @Generated("com.mysema.query.codegen.EntitySerializer")
    public class QUser extends EntityPathBase<User> {
    
        private static final long serialVersionUID = ...;
    
        public static final QUser user = new QUser("user");
    
        public final NumberPath<Integer> age = createNumber("age", Integer.class);
    
        public final StringPath id = createString("id");
    
        public final StringPath name = createString("name");
    
        public QUser(String variable) {
            super(User.class, forVariable(variable));
        }
    
        public QUser(Path<? extends User> path) {
            super(path.getType(), path.getMetadata());
        }
    
        public QUser(PathMetadata<?> metadata) {
            super(User.class, metadata);
        }
    }

    このクラスのおかげで、クエリを作成する必要はありません。

    ちなみに、Eclipseを使用している場合、このプラグインを導入すると、pomで次の警告が生成されます。

    Mavenインストール 正常に動作し、 QUser クラスは生成されますが、プラグインはpomで強調表示されます。

    簡単な修正は、 eclipse.iniでJDKを手動でポイントすることです。 :

    ...
    -vm
    {path_to_jdk}\jdk{your_version}\bin\javaw.exe

    5.3。 新しいリポジトリ

    次に、リポジトリでQueryDSLサポートを実際に有効にする必要があります。これは QueryDslPredicateExecutorを拡張するだけで実行できます。 インターフェース

    public interface UserRepository extends 
      MongoRepository<User, String>, QuerydslPredicateExecutor<User>

    5.4。

    サポートを有効にして、同じクエリを実装しましょう 前に説明したものと同じです。

    単純な平等から始めましょう:

    QUser qUser = new QUser("user");
    Predicate predicate = qUser.name.eq("Eric");
    List<User> users = (List<User>) userRepository.findAll(predicate);

    5.5。 StartingWith およびEndingWith

    同様に、前のクエリを実装して、 Aで始まる名前のユーザーを見つけましょう。 :

    QUser qUser = new QUser("user");
    Predicate predicate = qUser.name.startsWith("A");
    List<User> users = (List<User>) userRepository.findAll(predicate);
    

    cで終わるだけでなく :

    QUser qUser = new QUser("user");
    Predicate predicate = qUser.name.endsWith("c");
    List<User> users = (List<User>) userRepository.findAll(predicate);
    

    結果はセクション2.2、3.2、4.2と同じです。

    5.6。

    次のクエリは、前のセクションと同様に、20〜50歳のユーザーを返します。

    QUser qUser = new QUser("user");
    Predicate predicate = qUser.age.between(20, 50);
    List<User> users = (List<User>) userRepository.findAll(predicate);

    1. MongoDBでデータベースとコレクションを管理する方法

    2. unwindフィールドがmongodbに存在しない場合にすべての結果を取得する方法

    3. Redisコンテナを別のコンテナに接続する(Docker)

    4. HerokuにMongoDBをデプロイする方法