我想在我的应用程序中显示一个艺术家列表,用户可以通过它进行搜索。但是我不确定如何将其保存在Firestore中吗?
首先,我为每个DJ创建了一个带有文档的“ searchLists”集合,但这意味着文档的很多读取,所以这是不可能的。
现在,我创建了一个名为“艺术家”的文档,其中包含“ artistsDictionary”字段,其中包含所有艺术家。
| searchLists (collection)
* artists (document)
- artistsArray (array)
0: (map)
name: "Artist 0" (string)
1: (map)
name: "Artist 1" (string)
2: (map)
name: "Artist 2" (string)
然后我按照以下方式检索并解析数组:
let docRef = db.collection("searchLists").document("artists")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
guard let documentData = document.data() else { return }
let artistsDictionaryArray = documentData["artistsArray"] as? [[String: Any]] ?? []
let parsedArtists = artistsDictionaryArray.compactMap {
return SimpleArtist(dictionary: $0)
}
self.artistsArray = parsedArtists
} else {
print("Document does not exist")
}
}
(SimpleArtist是包含“名称”字段的结构。)
我的意思是,它可以工作,但是我还是Firestore的新手,这似乎还不错。是吗?还是这是我应该/应该如何做?
答案 0 :(得分:2)
首先,我为每个DJ创建了一个带有文档的“ searchLists”集合,但这意味着要读取大量文档,所以这是不可能的。
这是正确的方法,因此您应该继续进行下去。
我为什么这么说?
根据Cloud Firestore数据库中有关modeling data的官方文档:
Cloud Firestore经过优化,可以存储大量小文件。
将数据存储在数组中并不是一个坏选择,但这很有可能被使用,例如存储favorite djs
。我之所以这样说是因为文档在Firestore中有限制。因此,在文档中可以放入多少数据方面存在一些限制。根据有关usage and limits的官方文档:
文档的最大大小:1 MiB(1,048,576字节)
如您所见,单个文档中的数据总数限制为1 MiB。当我们谈论存储文本时,您可以存储很多,但是随着数组变大,请注意此限制。
答案 1 :(得分:2)
首先,亚历克斯的答案是100%正确的。
我想添加一些其他数据点,从长远来看可能对您有帮助。
第一项是数组。数组在NoSQL数据库中非常具有挑战性-尽管它们通过索引0、1、2提供逻辑序列数据,但它们的行为并不像代码中的数组一样。假设您想在索引处插入一个项目。好吧-您不能(*您可以,但这不只是一个简单的“插入”调用)。另外,您不能在查询中定位数组元素,这限制了它们的用途。 Firestore数组字段中最小的更改单位是整个字段-无法对字段的各个元素进行较小的更改。解决方法是不使用数组,而是让FireStore即时为您的数据``对象''创建documentID。节点的“键”
第二个问题-(当前可能不是问题)是如何处理数据的。假设您发布了应用程序,并且用户中有200万艺术家,那么按原样使用您的代码,一次下载所有这些数据可能不是最佳的UI体验,但是它可能会淹没用户的记忆。设备。因此,在设备和用户上处理数据的“块”变得容易得多。
所以我整理了一些示例代码来帮助解决这个问题。
首先是一个用于存储艺术家数据的类。只需跟踪documentID和艺术家名称即可。
class ArtistClass {
var docId = ""
var name = ""
init(aDocId: String, aName: String) {
self.docId = aDocId
self.name = aName
}
}
和一个用于保留艺术家的类数组。这可能是tableView的潜在数据源。
var artistArray = [ArtistClass]()
这是将艺术家作为文档而不是数组编写。 documentID是为每个艺术家创建的FireStore生成的“密钥”。
func writeArtists() {
let artistsRef = self.db.collection("artists")
let floyd = [
"name": "Pink Floyd"
]
let zep = [
"name": "Led Zeppelin"
]
let who = [
"name": "The Who"
]
artistsRef.addDocument(data: floyd)
artistsRef.addDocument(data: zep)
artistsRef.addDocument(data: who)
}
,然后读取所有所有艺术家的音乐。
func readArtists() {
let artistsRef = self.db.collection("artists")
artistsRef.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
let docId = document.documentID
let name = document.get("name") as! String
let artist = ArtistClass(aDocId: docId, aName: name)
self.artistArray.append(artist)
}
for a in self.artistArray { //prints the artists to console
print(a.docId, a.name)
}
}
}
}
所以您在Firestore中的数据看起来像这样
artists (collection)
8lok0a0ksodPSSKS
name: "Let Zeppelin"
WKkookokopkdokas
name: "The Who"
uh99jkjekkkokoks
name: "Pink Floyd"
那么酷的部分。假设您有一个tableView可以一次显示10位艺术家,并带有向下按钮以查看接下来的10位艺术家。
let artistsRef = self.db.collection("artists").order(by: "name").limit(to: 10)
哦-您会注意到排序功能现在是服务器而不是设备-因此,如果有一百万个艺术家,则会在服务器上对它进行排序,然后再将其交付给设备,
>然后,您还可以更轻松地对特定艺术家数据执行查询,而不必担心存储问题,因为每个艺术家都是他们自己的文档,而不是所有艺术家都在同一文档中。
希望有帮助!