MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

Panduan untuk Query di Spring Data MongoDB

1. Ikhtisar

Tutorial ini akan berfokus pada pembuatan jenis kueri yang berbeda di Spring Data MongoDB .

Kita akan melihat kueri dokumen dengan Query dan Kriteria kelas, metode kueri yang dibuat secara otomatis, kueri JSON, dan QueryDSL.

Untuk penyiapan Maven, lihat artikel pengantar kami.

2. Kueri Dokumen

Salah satu cara yang lebih umum untuk menanyakan MongoDB dengan Spring Data adalah dengan menggunakan Query dan Kriteria kelas, yang sangat mirip dengan operator asli.

2.1. Ada

Ini hanyalah sebuah kriteria yang menggunakan kesetaraan. Mari kita lihat cara kerjanya.

Dalam contoh berikut, kita akan mencari pengguna bernama Eric .

Mari kita lihat database kami:

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

Sekarang mari kita lihat kode kuerinya:

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

Seperti yang diharapkan, logika ini mengembalikan:

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

2.2. Regeks

Jenis kueri yang lebih fleksibel dan kuat adalah regex. Ini membuat kriteria menggunakan MongoDB $regex yang mengembalikan semua catatan yang cocok untuk ekspresi reguler untuk bidang ini.

Ini bekerja mirip dengan startingWith dan diakhiriDengan operasi.

Dalam contoh ini, kami akan mencari semua pengguna yang memiliki nama yang dimulai dengan A .

Berikut status databasenya:

[
    {
        "_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
    }
]

Sekarang mari kita buat kuerinya:

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

Ini menjalankan dan mengembalikan 2 catatan:

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

Berikut contoh cepat lainnya, kali ini mencari semua pengguna yang memiliki nama yang diakhiri dengan c :

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

Jadi hasilnya adalah:

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

2.3. Lt dan gt

Operator ini membuat kriteria menggunakan $lt (kurang dari) dan $gt (lebih besar dari) operator.

Mari kita ambil contoh singkat di mana kami mencari semua pengguna berusia antara 20 dan 50 tahun.

Basis datanya adalah:

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

Kode kueri:

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

Dan hasil untuk semua pengguna dengan usia lebih dari 20 tahun dan kurang dari 50 tahun:

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

2.4. Urutkan

Urutkan digunakan untuk menentukan urutan hasil.

Contoh di bawah menampilkan semua pengguna yang diurutkan berdasarkan usia dalam urutan menaik.

Pertama, ini data yang ada:

[
    {
        "_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
    }
]

Setelah menjalankan sort :

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

Dan inilah hasil kuerinya, diurutkan berdasarkan usia :

[
    {
        "_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. Dapat Dihalaman

Mari kita lihat contoh singkat menggunakan pagination.

Berikut status databasenya:

[
    {
        "_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
    }
]

Sekarang inilah logika kuerinya, cukup dengan meminta halaman berukuran 2:

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

Dan hasilnya, 2 dokumen tersebut, seperti yang diharapkan:

[
    {
        "_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. Metode Kueri yang Dihasilkan

Sekarang mari kita jelajahi jenis kueri yang lebih umum yang biasanya disediakan oleh Spring Data, kueri yang dibuat secara otomatis dari nama metode.

Satu-satunya hal yang perlu kita lakukan untuk memanfaatkan jenis kueri ini adalah mendeklarasikan metode pada antarmuka repositori:

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

3.1. FindByX

Kami akan mulai dengan sederhana, dengan menjelajahi jenis kueri findBy. Dalam hal ini, kita akan menggunakan find by name:

List<User> findByName(String name);

Sama seperti di bagian sebelumnya, 2.1, kueri akan memiliki hasil yang sama, menemukan semua pengguna dengan nama yang diberikan:

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

3.2. Mulai Dengan dan diakhiriDengan

Di bagian 2.2, kami menjelajahi regex kueri berbasis. Awalan dan akhiran tentu saja kurang kuat, namun cukup berguna, terutama jika kita tidak harus benar-benar mengimplementasikannya.

Berikut adalah contoh singkat tentang tampilan operasi:

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

Contoh penggunaan ini tentu saja akan sangat sederhana:

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

Dan hasilnya sama persis.

3.3. Antara

Mirip dengan bagian 2.3, ini akan menampilkan semua pengguna dengan usia antara ageGT dan ageLT:

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

Memanggil metode akan menghasilkan dokumen yang sama persis ditemukan:

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

3.4. Suka dan Pesan Oleh

Mari kita lihat contoh yang lebih canggih kali ini, menggabungkan dua jenis pengubah untuk kueri yang dihasilkan.

Kami akan mencari semua pengguna yang memiliki nama yang mengandung huruf A, dan kami juga akan mengurutkan hasil berdasarkan usia, dalam urutan menaik:

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

Untuk database yang kita gunakan di bagian 2.4, hasilnya adalah:

[
    {
        "_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. Metode Kueri JSON

Jika kami tidak dapat merepresentasikan kueri dengan bantuan nama metode atau kriteria, kami dapat melakukan sesuatu yang lebih rendah, gunakan @Kueri anotasi .

Dengan anotasi ini, kita dapat menentukan kueri mentah sebagai string kueri Mongo JSON.

4.1. Temukan Oleh

Mari kita mulai dari yang sederhana dan lihat bagaimana kita akan merepresentasikan a ditemukan oleh jenis metode pertama:

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

Metode ini harus mengembalikan pengguna dengan nama. Tempat penampung ?0 mereferensikan parameter pertama metode.

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

4.2. $regex

Kami juga dapat melihat kueri berbasis ekspresi reguler, yang tentu saja menghasilkan hasil yang sama seperti pada bagian 2.2 dan 3.2:

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

Penggunaannya juga sama persis:

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

4.3. $lt dan $gt

Sekarang mari kita implementasikan lt dan gt permintaan:

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

Sekarang metode tersebut memiliki 2 parameter, kami mereferensikan masing-masing parameter ini dengan indeks dalam kueri mentah, ?0 dan ?1:

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

5. Kueri KueriDSL

MongoRepositori memiliki dukungan yang baik untuk proyek QueryDSL, jadi kami juga dapat memanfaatkan API yang bagus dan aman untuk jenis itu di sini.

5.1. Ketergantungan Maven

Pertama, mari pastikan kita memiliki dependensi Maven yang benar yang didefinisikan di pom:

<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. T -kelas

QueryDSL menggunakan kelas-Q untuk membuat kueri, tetapi karena kami tidak benar-benar ingin membuatnya dengan tangan, kami perlu membuatnya entah bagaimana.

Kita akan menggunakan apt-maven-plugin untuk melakukannya:

<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>

Mari kita lihat Pengguna kelas, dengan fokus khusus pada @QueryEntity anotasi:

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

Setelah menjalankan proses tujuan siklus hidup Maven (atau tujuan lain apa pun setelah itu), plugin apt akan menghasilkan kelas baru di bawah target/generated-sources/java/{your package structure} :

/**
 * 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);
    }
}

Karena kelas inilah kita tidak perlu membuat kueri.

Sebagai catatan tambahan, jika kita menggunakan Eclipse, memperkenalkan plugin ini akan menghasilkan peringatan berikut di pom:

Maven memasang bekerja dengan baik dan QUser class dihasilkan, tetapi sebuah plugin disorot di pom.

Perbaikan cepat adalah dengan mengarahkan ke JDK secara manual di eclipse.ini :

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

5.3. Repositori Baru

Sekarang kita harus benar-benar mengaktifkan dukungan QueryDSL di repositori kita, yang dilakukan hanya dengan memperluas QueryDslPredicateExecutor antarmuka :

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

5.4. Persamaan

Dengan mengaktifkan dukungan, sekarang mari kita terapkan kueri yang sama seperti yang kami ilustrasikan sebelumnya.

Kita akan mulai dengan persamaan sederhana:

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

5.5. Mulai Dengan dan Berakhir Dengan

Demikian pula, mari kita terapkan kueri sebelumnya dan temukan pengguna dengan nama yang dimulai dengan A :

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

Serta diakhiri dengan c :

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

Hasilnya sama seperti pada bagian 2.2, 3.2 dan 4.2.

5.6. Antara

Kueri berikutnya akan menampilkan pengguna dengan usia antara 20 dan 50 tahun, mirip dengan bagian sebelumnya:

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

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Perintah MongoDB yang berbeda

  2. Mengambil jumlah kolom di MongoDB

  3. Parsing string tanggal ISO8601 hingga saat ini dengan Zona Waktu UTC

  4. Temukan MongoDB()

  5. MongoDB Tampilkan semua konten dari semua koleksi