MongoDB Java Tutorials - Hướng dẫn truy vấn dữ liệu trong MongoDB Sử dụng Java - Phần 3

Overview

Ở bài viết trước tôi đã hướng dẫn truy vấn dữ liệu trong MongoDB bao gồm Phần 1 về các trường cơ bản, Phần 2 về các trường embededd/nested. Tiếp tục bài viết này, tôi sẽ hướng dẫn truy vấn dữ liệu trong MongoDB Sử dụng Java Phần 3. Phần này tôi sẽ hướng dẫn truy vấn dữ liệu trên mảng của document (array in document) bao gồm mảng các thuộc tính đơn.

Data Examples

Với data model Post ví dụ ở các bài viết trước, tôi bổ sung thêm trường để ví dụ được đầy đủ các trường hợp:

@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Post {
    private String id;
    private String title;
    private String user;
    private String content;
    private List<String> tags;
    private List<Integer> numbers;
    private PostQuality postQuality;
    private int view;
    private boolean enable;
}

Xây dựng data lưu vào database:

private static void initDataExample(String ip, int port , String databaseName, String collection) {
    InsertDocument insertDocument = new InsertDocument(ip, port, databaseName);
    insertDocument.insertMany(collection, Post.class,
            Post.builder().id(UUID.randomUUID().toString()).title("Mongodb").user("Hungcdev").postQuality(new PostQuality(120, 50)).view(100).enable(true).build(),
            Post.builder().id(UUID.randomUUID().toString()).title("Spring").user("Hungcdev").postQuality(new PostQuality(120, 100)).view(200).enable(false).build(),
            Post.builder().id(UUID.randomUUID().toString()).title("Java").user("AtomPtit").postQuality(new PostQuality(50, 10)).view(300).enable(true).build(),
            Post.builder().id(UUID.randomUUID().toString()).title("Spring Boot").user("AtomPtit").postQuality(new PostQuality(70, 50)).view(400).enable(true).build(),
            Post.builder().id(UUID.randomUUID().toString()).title("PHP").user("HungHoi").postQuality(new PostQuality(150, 120)).view(500).enable(true).build()
    );
}

Query an Array

1. $all

Để truy vấn với điều kiện mảng chứa các phần tử, ta sử dụng $all. Ví dụ dưới đây tìm kiếm document với điều kiện mảng tags có chứa các phần tử: mongodb, java:

private static void findArrayOfDocumentExample1(String ip, int port, String databaseName, String collection) {
    QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);

    /* tim kiem document voi tags co chua cac phan tu: mongodb, java */
    Bson query = Filters.all("tags", List.of("mongodb", "java"));

    List<Post> postList = queryDocument.find(collection, Post.class, query);
    System.out.println("--- Document trong Collection Post voi "+ query.toString() + "---");
    postList.forEach(post -> System.out.println(post.toString()));
    System.out.println("--- End ---");
}
OUTPUT:
--- Document trong Collection Post voi Operator Filter{fieldName='tags', operator='$all', value=[mongodb, java]}---
Post(id=5f63c96a-8551-41bd-a5dc-80124d20de57, title=Mongodb, user=Hungcdev, content=null, tags=[mongodb, java], numbers=[10, 30], postQuality=null, view=100, enable=true)
Post(id=f4d10d34-3117-4081-b42d-c97c677f5b48, title=Java, user=AtomPtit, content=null, tags=[java, mongodb], numbers=[30, 40], postQuality=null, view=0, enable=true)
Post(id=5d239f26-5e6a-46a6-b241-b100b092a74a, title=Spring Boot, user=AtomPtit, content=null, tags=[spring, java, mongodb], numbers=[20, 30, 40], postQuality=null, view=0, enable=true)
--- End ---

2. $eq

Để truy vấn so sánh toàn bộ danh sách trong một mảng, chúng ta sử dùng toán tử $eq. Ví dụ câu lệnh dưới đây document phải thỏa mãn mảng tags có chính xác 2 phân tử lần lượt là mongodb và java. Thiếu hoặc thừa bất kỳ phần tử nào hoặc không đúng thứ tự thì đều không thỏa mãn:

private static void findArrayOfDocumentExample2(String ip, int port, String databaseName, String collection) {
    QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);

    /* tim kiem document voi tags co chinh xac 2 phan tu theo thu tu la: mongodb, java */
    Bson query = Filters.eq("tags", List.of("mongodb", "java"));

    List<Post> postList = queryDocument.find(collection, Post.class, query);
    System.out.println("--- Document trong Collection Post voi "+ query.toString() + "---");
    postList.forEach(post -> System.out.println(post.toString()));
    System.out.println("--- End ---");
}
OUTPUT:
--- Document trong Collection Post voi Filter{fieldName='tags', value=[mongodb, java]}---
Post(id=5f63c96a-8551-41bd-a5dc-80124d20de57, title=Mongodb, user=Hungcdev, content=null, tags=[mongodb, java], numbers=[10, 30], postQuality=null, view=100, enable=true)
--- End --

Để tìm kiếm với điều kiện mảng chứa phần tử với giá trị được chỉ định, ta cũng sự dụng $eq:

private static void findArrayOfDocumentExample3(String ip, int port, String databaseName, String collection) {
    QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);

    /* tim kiem document voi tags co chua phan tu: mongodb */
    Bson query = Filters.eq("tags", "mongodb");

    List<Post> postList = queryDocument.find(collection, Post.class, query);
    System.out.println("--- Document trong Collection Post voi "+ query.toString() + "---");
    postList.forEach(post -> System.out.println(post.toString()));
    System.out.println("--- End ---");
}
OUTPUT:
--- Document trong Collection Post voi Filter{fieldName='tags', value=mongodb}---
Post(id=5f63c96a-8551-41bd-a5dc-80124d20de57, title=Mongodb, user=Hungcdev, content=null, tags=[mongodb, java], numbers=[10, 30], postQuality=null, view=100, enable=true)
Post(id=f4d10d34-3117-4081-b42d-c97c677f5b48, title=Java, user=AtomPtit, content=null, tags=[java, mongodb], numbers=[30, 40], postQuality=null, view=0, enable=true)
Post(id=5d239f26-5e6a-46a6-b241-b100b092a74a, title=Spring Boot, user=AtomPtit, content=null, tags=[spring, java, mongodb], numbers=[20, 30, 40], postQuality=null, view=0, enable=true)
--- End ---

3. $elemMatch

Khi chỉ định kết hợp nhiều điều kiện áp dụng cho mảng, bạn có thể chỉ định truy vấn với 2 cách:

  • Sự kết hợp của các phần tử trong mảng đáp ứng các điều kiện.
  • Một phần tử trong mảng thỏa mãn tất cả điều kiện

Sự kết hợp của các phần tử trong mảng đáp ứng các điều kiện

Ví dụ truy vấn các document với điều kiện các phần từ trong mảng numbers có phần tử lơn hơn 15, có phần nhỏ hơn 25.

private static void findArrayOfDocumentExample4(String ip, int port, String databaseName, String collection) {
    QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);

    /* tim kiem document voi numbers co it nhat mot phan tu > 15, co it nhat mot phan tu < 25, hoac la mot phan tu thoa ma ca 2 dieu kien */
    Bson query = Filters.and(Filters.gt("numbers", 15), Filters.lt("numbers", 25));

    List<Post> postList = queryDocument.find(collection, Post.class, query);
    System.out.println("--- Document trong Collection Post voi "+ query.toString() + "---");
    postList.forEach(post -> System.out.println(post.toString()));
    System.out.println("--- End ---");
}
OUTPUT:
--- Document trong Collection Post voi And Filter{filters=[Operator Filter{fieldName='numbers', operator='$gt', value=15}, Operator Filter{fieldName='numbers', operator='$lt', value=25}]}---
Post(id=5f63c96a-8551-41bd-a5dc-80124d20de57, title=Mongodb, user=Hungcdev, content=null, tags=[mongodb, java], numbers=[10, 30], postQuality=null, view=100, enable=true)
Post(id=91f889b6-b6ad-4676-865e-b73727b2e6a6, title=Spring Java, user=Hungcdev, content=null, tags=[spring, java], numbers=[20, 30], postQuality=null, view=0, enable=false)
Post(id=5d239f26-5e6a-46a6-b241-b100b092a74a, title=Spring Boot, user=AtomPtit, content=null, tags=[spring, java, mongodb], numbers=[20, 30, 40], postQuality=null, view=0, enable=true)
--- End ---

Một phần tử trong mảng thỏa mãn tất cả điều kiện

Truy vấn mảng với việc ít nhất một phần tử trong mảng đáp ứng tất cả điều kiện - sử dụng toán tử $elemMatch. Ví dụ truy vấn các document với điều kiện ít nhất một phần tử trong mảng numbers phải thỏa mãn lớn hơn 15 và nhỏ hơn 25

private static void findArrayOfDocumentExample5(String ip, int port, String databaseName, String collection) {
    QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);

    /* tim kiem document voi numbers chua it nhat 1 phan tu x voi dieu kien: 15 < x < 25 */
    Bson query = Filters.elemMatch("numbers", Document.parse("{ $gt: 15, $lt: 25 }"));

    List<Post> postList = queryDocument.find(collection, Post.class, query);
    System.out.println("--- Document trong Collection Post voi "+ query.toString() + "---");
    postList.forEach(post -> System.out.println(post.toString()));
    System.out.println("--- End ---");
}
OUTPUT:
--- Document trong Collection Post voi com.mongodb.client.model.Filters$1@662b4c69---
Post(id=91f889b6-b6ad-4676-865e-b73727b2e6a6, title=Spring Java, user=Hungcdev, content=null, tags=[spring, java], numbers=[20, 30], postQuality=null, view=0, enable=false)
Post(id=5d239f26-5e6a-46a6-b241-b100b092a74a, title=Spring Boot, user=AtomPtit, content=null, tags=[spring, java, mongodb], numbers=[20, 30, 40], postQuality=null, view=0, enable=true)
--- End ---

4. Index Array

Để truy vấn với điều kiện một phần tử trong mảng với vị trí cụ thể, bạn sử dụng ký tự . sau đó là vị trí của phần tử (vị trí bắt đầu từ 0).

Ví dụ truy vấn các document với phần tử thứ 2 trong mảng numbers bằng 40:

private static void findArrayOfDocumentExample6(String ip, int port, String databaseName, String collection) {
    QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);

    /* tim kiem document voi numbers co phan tu thu 2 bang 40 */
    Bson query = Filters.eq("numbers.1", 40);

    List<Post> postList = queryDocument.find(collection, Post.class, query);
    System.out.println("--- Document trong Collection Post voi "+ query.toString() + "---");
    postList.forEach(post -> System.out.println(post.toString()));
    System.out.println("--- End ---");
}
OUTPUT:
--- Document trong Collection Post voi Filter{fieldName='numbers.1', value=40}---
Post(id=f4d10d34-3117-4081-b42d-c97c677f5b48, title=Java, user=AtomPtit, content=null, tags=[java, mongodb], numbers=[30, 40], postQuality=null, view=0, enable=true)
--- End ---

5. $size

Sử dụng $size để truy vấn số lượng phần tử trong mảng, ví dụ chọn các document mà có mảng có 3 phần tử:

private static void findArrayOfDocumentExample7(String ip, int port, String databaseName, String collection) {
    QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);

    /* tim kiem document voi numbers co 3 phan tu */
    Bson query = Filters.size("numbers", 3);

    List<Post> postList = queryDocument.find(collection, Post.class, query);
    System.out.println("--- Document trong Collection Post voi "+ query.toString() + "---");
    postList.forEach(post -> System.out.println(post.toString()));
    System.out.println("--- End ---");
}
--- Document trong Collection Post voi Operator Filter{fieldName='numbers', operator='$size', value=3}---
Post(id=5d239f26-5e6a-46a6-b241-b100b092a74a, title=Spring Boot, user=AtomPtit, content=null, tags=[spring, java, mongodb], numbers=[20, 30, 40], postQuality=null, view=0, enable=true)
--- End ---

Source code

Source code liên quan về bài viết: https://github.com/hungcdev/MongoDB-Java-Tutorials