MongoDB Java Tutorials - Hướng dẫn truy vấn dữ liệu trong MongoDB Sử dụng Java - Phần 4
Overview
Ở bài viết trước tôi đã hướng dẫn truy vấn dữ liệu trong MongoDB dựa trên mảng của document
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 4. Phần này tôi sẽ hướng dẫn truy vấn dữ liệu dựa trên mảng các embedded/nested document.
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 List<Comment> comments;
private PostQuality postQuality;
private int view;
private boolean enable;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Comment {
private String user;
private String message;
private int likeNumber;
}
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").comments(List.of(new Comment("user1", "good post",10), new Comment("user2", "great! Tks",20))).build(),
Post.builder().id(UUID.randomUUID().toString()).title("Spring Java").user("Hungcdev").comments(List.of(new Comment("user2", "thank so much",15), new Comment("user1", "thankkkkk",20))).build(),
Post.builder().id(UUID.randomUUID().toString()).title("Java").user("AtomPtit").comments(List.of(new Comment("user3", "good post",10), new Comment("user1", "thankkkkk",15))).build(),
Post.builder().id(UUID.randomUUID().toString()).title("Spring Boot").user("AtomPtit").comments(List.of(new Comment("user2", "thank so much",20), new Comment("user3", "thankkkkk",30))).build(),
Post.builder().id(UUID.randomUUID().toString()).title("Spring").user("HungHoi").comments(List.of(new Comment("user1", "great! Tks",25))).build()
);
}
Query a Document nested in an Array
Để truy vấn document với điều kiện một nested Document trong mảng ta sử dụng toán tử $eq
. Ví dụ dưới đây truy vấn các document với điều kiện mảng comments
có document thỏa mãn giá trị chỉ định:
private static void queryArrayEmbeddedDocument1(String ip, int port, String databaseName, String collection) {
QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);
/* tim kiem document voi comments co chua document comment thoa man cac gia tri */
Bson query = Filters.eq("comments", new Comment("user1", "thankkkkk",15));
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='comments', value=Comment(user=user1, message=thankkkkk, likeNumber=15)}---
Post(id=47f78e7a-2869-49fd-a7b6-6aa371b33aa2, title=Java, user=AtomPtit, content=null, tags=null, numbers=null, comments=[Comment(user=user3, message=good post, likeNumber=10), Comment(user=user1, message=thankkkkk, likeNumber=15)], postQuality=null, view=0, enable=false)
--- End ---
Query a Field in an Array of Documents
Để truy vấn các document với điều kiện một trường thuộc nested document trong mảng, mà không biết trước vị trí cụ thể của nested document đó nằm ở đâu trong mảng, bạn sử dụng ký tự .
nối giữa tên mảng và tên trường.
Ví dụ dưới đây truy vấn các document nơi mà mảng comments
có ít nhất một document mà trường user
là user3:
private static void queryArrayEmbeddedDocument2(String ip, int port, String databaseName, String collection) {
QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);
/* tim kiem document voi comments co chua document ma truong user co gia tri la user3 */
Bson query = Filters.eq("comments.user", "user3");
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='comments.user', value=user3}---
Post(id=47f78e7a-2869-49fd-a7b6-6aa371b33aa2, title=Java, user=AtomPtit, content=null, tags=null, numbers=null, comments=[Comment(user=user3, message=good post, likeNumber=10), Comment(user=user1, message=thankkkkk, likeNumber=15)], postQuality=null, view=0, enable=false)
Post(id=d9c15435-528e-48f5-9d64-523b5de08818, title=Spring Boot, user=AtomPtit, content=null, tags=null, numbers=null, comments=[Comment(user=user2, message=thank so much, likeNumber=20), Comment(user=user3, message=thankkkkk, likeNumber=30)], postQuality=null, view=0, enable=false)
--- End --
Để truy vấn với điều kiện một nested document trong mảng với vị trí cụ thể, bạn sử dụng ký tự .
và vị trí của nested document đó (vị trí bắt đầu từ 0).
Ví dụ dưới đây truy vấn các document nơi mà mảng comments
có document ở vị trí đầu tiền mà trường user là user3:
private static void queryArrayEmbeddedDocument3(String ip, int port, String databaseName, String collection) {
QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);
/* tim kiem document voi comments co document vi tri dau tien ma truong user co gia tri la user3 */
Bson query = Filters.eq("comments.0.user", "user3");
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='comments.0.user', value=user3}---
Post(id=47f78e7a-2869-49fd-a7b6-6aa371b33aa2, title=Java, user=AtomPtit, content=null, tags=null, numbers=null, comments=[Comment(user=user3, message=good post, likeNumber=10), Comment(user=user1, message=thankkkkk, likeNumber=15)], postQuality=null, view=0, enable=false)
--- End ---
Khi bạn kết hợp nhiều điều kiện trên các trường thuộc nested document trong mảng, bạn có thể chỉ định truy vấn:
- Một Document có các trường đáp ứng tất cả điều kiện
- Bất kỳ sự kết hợp các trường của các document đáp ứng tất cả điều kiện
Để áp dụng một document thỏa mãn tất cả điều kiện, ta sử dụng toán tử $elemMatch
. Ví dụ dưới đây truy vấn các document với điều kiện mảng comments
có ít nhất một document thỏa mãn các điều kiện trường user
là user1 và trường likeNumber
có giá trị 20
private static void queryArrayEmbeddedDocument4(String ip, int port, String databaseName, String collection) {
QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);
/* tim kiem document voi comments co it nhat mot document ma co truong user la user1 va truong likeNumber la 20 */
Bson query = Filters.elemMatch("comments", Filters.and(Filters.eq("user", "user1"), Filters.eq("likeNumber", 20)));
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@290222c1---
Post(id=bdc502ce-7558-4ee2-ab2d-f5ba01565f65, title=Spring Java, user=Hungcdev, content=null, tags=null, numbers=null, comments=[Comment(user=user2, message=thank so much, likeNumber=15), Comment(user=user1, message=thankkkkk, likeNumber=20)], postQuality=null, view=0, enable=false)
--- End ---
Nếu không sử dụng toán tử $elemMatch
, truy vấn sẽ áp dụng cho bất kỳ trường nào thuộc các document thỏa mãn các điều kiện. Ví dụ truy vấn các document với điều kiện mảng comments
có document thỏa mãn điều kiện trường user
là user1 và có document thỏa mãn điều kiện trường likeNumber
có giá trị 20:
private static void queryArrayEmbeddedDocument5(String ip, int port, String databaseName, String collection) {
QueryDocument queryDocument = new QueryDocument(ip, port,databaseName);
/* tim kiem document voi comments co document ma truong user la user1 va co document ma truong likeNumber bang 20 */
Bson query = Filters.and(Filters.eq("comments.user", "user1"), Filters.eq("comments.likeNumber", 20));
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=[Filter{fieldName='comments.user', value=user1}, Filter{fieldName='comments.likeNumber', value=20}]}---
Post(id=45dc12f4-8968-444b-98a9-3ac75d1f6281, title=Mongodb, user=Hungcdev, content=null, tags=null, numbers=null, comments=[Comment(user=user1, message=good post, likeNumber=10), Comment(user=user2, message=great! Tks, likeNumber=20)], postQuality=null, view=0, enable=false)
Post(id=bdc502ce-7558-4ee2-ab2d-f5ba01565f65, title=Spring Java, user=Hungcdev, content=null, tags=null, numbers=null, comments=[Comment(user=user2, message=thank so much, likeNumber=15), Comment(user=user1, message=thankkkkk, likeNumber=20)], postQuality=null, view=0, enable=false)
--- End ---
Source code
Source code liên quan về bài viết: https://github.com/hungcdev/MongoDB-Java-Tutorials