Tôi sẽ xem tài liệu và hướng dẫn của Firestore. Mẫu mã của tôi dưới đây sử dụng AngularFire2.Cách tốt nhất để lấy dữ liệu từ các bộ sưu tập được lồng trong tài liệu trong Firestore là gì?
Hãy xem xét một "chat" bộ sưu tập tương tự như các ví dụ được cung cấp ở đây: https://firebase.google.com/docs/firestore/manage-data/structure-data
Họ khuyên loại cấu trúc này nhưng tôi không thấy nơi họ thảo luận nhận được tất cả các dữ liệu một cách hiệu quả.
Mỗi tài liệu trò chuyện có tính chất, một bộ sưu tập của các thành viên, và một tập hợp các thông điệp:
- chatsCollection
- chatDocument
- [chèn lĩnh vực trò chuyện dữ liệu ở đây]
- membersCollection
- memberDocument
- [chèn trường dữ liệu thành viên tại đây]
- memberDocument
- messagesCollection
- messageDocument
- [chèn trường dữ liệu lời nhắn ở đây]
- messageDocument
- chatDocument
truy vấn FireStore là nông cạn, mà có thể là tuyệt vời đôi khi. Sự hiểu biết của tôi là không có cách nào để truy vấn sâu và nhận các bộ sưu tập lồng nhau. Vì vậy, các phương pháp hay nhất và cách rắc rối nhất để làm điều này là gì?
Hiện tại tôi đang truy xuất và ánh xạ các ảnh chụp nhanh đến các đối tượng có ID và thêm dữ liệu lồng nhau vào dữ liệu tài liệu gốc với các truy vấn và ánh xạ bổ sung và tôi không hài lòng với cách tiếp cận của mình. ngay cả với cấu trúc Firebase không chuẩn hóa.
Mã này ví dụ chỉ là lập bản đồ trên các thành viên, cộng lại trong các tin nhắn là một câu chuyện hoàn toàn khác ...
getChatsFromFirestore() {
this.chats = this.dataSvc.getChatsFromFirestore().snapshotChanges()
.map(chatSnaps => {
return chatSnaps.map(chat => {
const chatData = chat.payload.doc.data();
const chatId = chat.payload.doc.id;
return this.dataSvc.getMembersForChat(chatId)
.snapshotChanges()
.map(memberSnaps => {
return memberSnaps.map(member => {
const data = member.payload.doc.data();
const id = member.payload.doc.id;
return { id, ...data }
});
})
.map(members => {
return { chatId, ...chatData, members: members };
});
})
})
.flatMap(chats => Observable.combineLatest(chats));
}
Và từ dịch vụ:
getChatsFromFirestore() {
return this.fsd.collection<any>('chats');
}
getChatFromFirestoreById(id: string) {
return this.fsd.doc(`chats/${id}`);
}
getMembersForChat(chatId) {
return this.getChatFromFirestoreById(chatId).collection('members');
}
Tôi đoán có một cuộc tranh cãi vào đây để sao chép & denormalizing dữ liệu theo quá trình cho cơ sở dữ liệu thời gian thực (một cái gì đó như [câu trả lời này ] (https://stackoverflow.com/a/30699277/2754146)), nhưng tôi cũng hy vọng có một quy trình khác nhau/tốt hơn để tham gia dữ liệu trong Firestore. – Grimthorr
Điểm tốt và tôi đã làm lệch và làm mất dữ liệu một chút trong trường hợp này. Ví dụ: mỗi cuộc trò chuyện chứa các thành viên có ID tài liệu phù hợp với UID có thể được sử dụng để lấy tất cả dữ liệu của thành viên đó, nhưng cũng chứa tên của người dùng. Mỗi thư cá nhân cũng chứa trường "authorName" và trường "sentBy" giữ UID của người dùng đó một lần nữa ... vẫn có thể nhận tất cả dữ liệu lồng nhau trong tài liệu phòng chat mà không có cuộc gọi đệ quy đến DB hoặc ít nhất với ít chi tiết hơn mã sẽ được mát mẻ. – Methodician
Nếu bạn lưu id với 'chatDocument' làm trường, bạn có thể sử dụng' .valueChanges() 'và lấy id. nhanh hơn '.snapshotChanges()'. – Hareesh