有没有办法在查询主集合时将子集合映射到结构? (火库)
Posted
技术标签:
【中文标题】有没有办法在查询主集合时将子集合映射到结构? (火库)【英文标题】:Is there a way to map a sub-collection into a struct while querying the main collection? (Firestore) 【发布时间】:2021-10-12 18:35:18 【问题描述】:有没有办法在查询主集合时将子集合映射到结构中?
我的子集合结构是:
-conversations (collection)
--- "users" : [array of two users]
--- messages (subcollection)
------- "created by": "sender"
------- "date" : timestamp
------- "msg" : "help me guys I'm stuck with this damn chat feature"
我在某处读到查询很浅,这意味着您只会获得您正在查询的集合的字段,但也许在查询第一个集合之后除了嵌套查询循环之外还有另一种方法
func getFilteredConversations(query: String)
if (user != nil)
db.collection("conversations").whereField("users", arrayContains: user!.displayName)
.order(by: "createdTime")
.addSnapshotListener (querySnapshot, error) in
guard let documents = querySnapshot?.documents else
print("no conversations found")
return
//mapping
self.chats = documents.map (queryDocumentSnapshot) -> Conversation in
let data = queryDocumentSnapshot.data()
let docId = queryDocumentSnapshot.documentID
let users = data["users"] as? [String] ?? [""]
let unreadmsg = data["hasUnreadMessage"] as? Bool ?? false
//MARK: - GET MESSAGES
self.db.collection("conversations").document(docId).collection("messages")
.order(by: "date")
.addSnapshotListener (querySnapshot, err) in
guard let documents = querySnapshot?.documents else
print("no messages found")
return
var mensajes = [Message]()
mensajes = documents.map (queryDocumentSnapshot) -> Message in
let data = queryDocumentSnapshot.data()
let docId = queryDocumentSnapshot.documentID
let createdby = data["created_by"] as? String ?? ""
let msg = data["msg"] as? String ?? ""
let date = data["date"] as? Timestamp ?? Timestamp()
return Message(createdBy: createdby, msg: msg, date: date, id: docId)
print("Users: \(users)")
return Conversation(id: docId, users: users, messages: mensajes, hasUnreadMessage: unreadmsg)
这是模型
struct Conversation: Decodable, Identifiable
//var id: UUID person.id
@DocumentID var id: String? = UUID().uuidString
var users: [String] = [""]
var messages: [Message] = []
var hasUnreadMessage : Bool = false
struct Message: Decodable
var createdBy: String?
var msg: String?
@ServerTimestamp var date : Timestamp?
var id : String?
【问题讨论】:
【参考方案1】:您自己似乎已经找到了答案:Firestore 查询很浅。在读取父文档时无法从子集合中读取。跨集合查询的唯一方法是使用collection group query,这似乎不适用于此处。
考虑是否值得通过客户端代码或云函数在父文档中复制来自对话的最新消息。这样,您就可以减少为向用户显示初始消息而必须阅读的文档数量。
【讨论】:
感谢您的回答,我只想在每次聊天中添加新消息时获得实时更新。集合组查询会完成吗?或者我应该为每个聊天/对话添加一个听众?我知道我最多有 100 个 要更新特定对话的消息,您可以收听messages
子集合。要跨多个对话收听,收集组查询或将数据复制到父文档中是您的两个选择 - 正如我的回答中所述。以上是关于有没有办法在查询主集合时将子集合映射到结构? (火库)的主要内容,如果未能解决你的问题,请参考以下文章