我刚来自关系数据库学校,处理JSON数据库对新来者来说并不是一件容易的事。我有这种结构来存储用户:
{
"users" : {
"0CcKvNkOm5fVqL" : {
"birthday" : 564688000,
"country" : "US",
"email" : "email@live.com",
"firstName" : "John",
"gender" : "male",
"isOnline" : true,
"lastLoginDate" : 1468166460486,
"lastName" : "Paul",
"learningLanguages" : [ {
"language" : "fr_FR",
"levelID" : 2
} ],
"profileImage" : "https://firebasestorage.googleapis.com/image.jpg",
"providerID" : "Firebase",
"registrationDate" : 1468168460486,
"speakingLanguages" : [ {
"language" : "es_ES",
"levelID" : 7
} ]
}
}
}
我在我的应用中提供了一个搜索屏幕,用户可以搜索其他用户,他们可以合并所有这些过滤器参数:
示例:
获取10
用户starting from index 0
:
male
"US"
的speaks "da_DK"
levelID 2
或/和 "fr_FR"
any level
with
等级1 **and/or**
学习“ar_AR”with
等级4` age range between 18 and 24
isOnline
和 last login date
排序。 当假设有一个名为users_languages的表时,这是一个简单的SQL任务:
SELECT ...
FROM users AS u
JOIN users_languages AS l
ON u.id = l.id
WHERE u.gender = "male"
AND u.age BETWEEN 18 AND 24 // need claculation but let's keep it simple
AND u.country = "US"
AND ((l.language = "de_DE" AND l.mode = "learning" AND l.level = 1) OR (l.language = "ar_AR" AND l.mode = "learning" AND l.level = 4))
....
ORDER BY isOnline, lastLoginDate DESC
LIMIT 0,10
我的问题:
答案 0 :(得分:9)
答案是:您无法在Firebase中搜索此类型。
让我提出一个墙上的答案,希望能够找到解决方案。
要相当弗兰克: 正如Frank在他的论点和链接中提到的那样,利用ElasticSearch等其他产品可以成为一种解决方案。虽然它们确实提供了可扩展性,但它增加了另一种产品。我建议进一步探讨这些选择。
过滤很酷: 第二种解决方案是过滤代码。虽然这对于成千上万条记录来说是一个很好的解决方案,但它不能扩展到数十/数十万条记录。但是,如果您具有复杂的数据结构和有限的数据量,这是最佳解决方案。
在这方面,如果UI的结构使其工作,您甚至可以使用数百万条记录来过滤代码。确定一到两个主要搜索,例如性别。然后对所有女性执行查询。这会将您的数据集减少一半,并且在代码中更易于管理。您还可以进一步减少数据集 - 请参阅下一节。
变化很好: 另一种选择是构建数据以匹配您将要执行的查询类型。举个简单的例子:假设您有三个要查询的项目; gender_country_age
您的Firebase结构将是
users
-Jyiai09jsi
data: "male_US_40"
-Jqkjisjida
date: "male_US_27"
-JyHYjlkall
data: "male_US_30"
然后查询年龄在30到40岁之间的美国所有男性用户
usersRef.queryOrderedByChild("data").queryStartingAtValue("male_US_30")
.queryEndingAtValue("male_US_40").observeSingleEventOfType(
.Value, withBlock: { snapshot in
print(snapshot)
})
这方面的优势在于它具有可扩展性,但缺点是你不能只查询美国用户。另一方面,这是一个小得多的数据集,您可以在代码中进一步过滤。
重复数据是您的朋友: 好消息是,这也是一个解决方案:磁盘空间很便宜所以重复你的数据
user_countries
US
-Jyiai09jsi: true
-Jqkjisjida: true
-JyHYjlkall: true
UK
etc etc
user_gender
male
-Jyiai09jsi: true
-Jqkjisjida: true
-JyHYjlkall: true
female
etc etc
user_speaks
da_UK
users
fr_FR
users
此结构可让您快速访问数据组;国家,性别等我在这里使用true作为占位符,但从技术上讲,你也可以在该位置拥有每个用户节点。但是,在查询期间,这将再次读取大量数据;一堆真实的'节点是非常少量的数据,即使有数千个节点。
SQL ftw! 还需要考虑的是如何使用Firebase的异步特性。您是否真的需要将这些数据存储在Firebase中,或者您是否可以将该数据存储在另一个基于云的SQL服务器中,以便在Firebase中查询和存储指向该数据的链接。这样,您可以通过SQL查询您的内容,然后使用Firebase进行消息传递,更新等。
最后的想法如果您想要进行这些类型的搜索,最好的选择是以尽可能快地减少其数据的方式构建数据,然后过滤其余的数据。码。想象一下,有一百万条记录,然后查询male_US_30_FR。现在你有几千条记录可以轻松加载并在代码中进一步过滤
我希望其中一个或两者的组合有所帮助。