我的数据库结构如下:
posts:
pid1:
timestamp: 111
pod:
title: "eggs"
pid2:
timestamp: 222
pod:
title: "milk"
pid3:
timestamp: 333
pod:
title: "bread"
users_posts:
uid1:
pid1: true
pid2: true
我想获取uid1
包含特定子字符串的所有title
帖子。
例如:
输入: 子字符串:“ gs”,userId:uid1
输出:pid1
最好的方法是什么?
这是我到目前为止所做的:
func queryPosts(withSearchText searchText: String, userId: String, completion: @escaping (Post) -> Void) {
REF_USER_POSTS.child(userId).observeSingleEvent(of: .value) { (snapshot) in
let ids = (snapshot.value as! [String: Any]).keys
for id in ids {
REF_POSTS.child(id).observeSingleEvent(of: .value) { (snapshot) in
if let dict = snapshot.value as? [String: Any],
let title = ((dict["pod"] as? [String: Any])?["title"] as? String)?,
title.contains(searchText) {
print("found result", id)
}
}
}
}
}
答案 0 :(得分:0)
如上面评论中所讨论的,您必须按如下所示修改数据库结构
posts:
pid1:
timestamp: 111
createdBy: "uid1"
title: "eggs"
pid2:
timestamp: 222
createdBy: "uid1"
title: "milk"
pid3:
timestamp: 333
createdBy: "uid2"
title: "bread"
users_posts:
uid1:
pid1: true
pid2: true
用于按特定用户获取所有帖子并匹配字符串,请使用以下查询
FirebaseFirestore.getInstance().collection("posts")
.whereEqualTo("createdBy","uid1")
.whereEqualTo("title","eggs")
.get()
.addOnCompleteListener {
//all posts written by user and matching the title eggs
}
.addOnFailureListener {
it.printStackTrace()
}
在最初运行此查询时,它将在logcat中显示错误,提示generate composite index检查logcat并单击链接以生成复合索引,在创建索引后它将起作用
答案 1 :(得分:0)
您可以使用深度查询轻松查询子节点。
例如,假设您要查询title =“ milk”的所有节点
dock container run --name nginx --volume /hosthome/mazoo/DockerExampleFolder/html:/usr/share/nginx/html -p 80:80 nginx:latest
输出为
func performDeepQuery() {
let postsRef = self.ref.child("more_posts")
let query = postsRef.queryOrdered(byChild: "pod/title").queryEqual(toValue: "milk")
query.observeSingleEvent(of: .value, with: { snapshot in
let allChildren = snapshot.children.allObjects as! [DataSnapshot]
for snap in allChildren {
let postId = snap.key
let timestamp = snap.childSnapshot(forPath: "timestamp").value as? String ?? "No Timestamp"
print(postId, timestamp)
}
})
}
话虽如此,这不会查询特定用户的帖子。这将查询所有帖子。但是,您可以通过添加另一个节点以使节点特定于用户来轻松解决该问题
pid2 222
,查询将为
pid2:
timestamp: 222
pod:
title: "milk"
uid_title: "uid1_milk"
这是一个复合值,在NoSQL数据库中很常见。
如果要扩展该范围,请翻转该值,以便可以将多个用户链接到单个帖子
let query = postsRef.queryOrdered(byChild: "pod/title").queryEqual(toValue: "uid1_milk")
然后您可以查询任何有牛奶的用户。
pid2:
timestamp: 222
pod:
title: "milk"
uid1_milk: true
uid2_milk: true
这可能不适用于您的用例,但这是一个非常不错的选择,并且可以用于将来的发展。