- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在解决如何最好地构造我的(非常简单的)Firestore应用程序时遇到一些麻烦。我有一组这样的用户:
users: {
'A123': {
'name':'Adam'
},
'B234': {
'name':'Bella'
},
'C345': {
'name':'Charlie'
}
}
users: {
'A123': {
'name':'Adam',
'likedBy': {
'B234':true,
},
'disLikedBy': {
'C345':true
}
},
'B234': {
'name':'Bella'
},
'C345': {
'name':'Charlie'
}
}
var usersRef = firebase.firestore().collection('users')
.where('likedBy.C345','==',false)
.where('dislikedBy.C345','==',false)
最佳答案
没有完美的解决方案可以解决此问题,但是您可以根据需要进行权衡取舍。
选项:过扫描与欠扫描
请记住,Cloud Firestore仅允许查询的扩展独立于数据集的总大小。
这对于防止您构建可以在10个文档中进行测试的东西确实很有帮助,但是一旦您投入生产并大受欢迎,它就会立即崩溃。不幸的是,这种类型的问题不适合那种可扩展的模式,您拥有的配置文件越多,人们创建的喜欢度越高,回答您想要的查询所需的时间就越长。
然后的解决方案是找到一个或多个可扩展且最能代表您想要的查询。我可以想到两种选择,它们以不同的方式进行权衡:
过扫描->进行更广泛的查询,然后在客户端进行过滤
欠扫描->进行一个或多个狭窄的查询,可能会遗漏一些结果。
过扫描
在“过扫描”选项中,您基本上是在交易成本增加而获得100%的准确性。
给定您的用例,我想这实际上可能是您的最佳选择。由于配置文件的总数可能比个人喜欢的配置文件的数量大几个数量级,因此过扫描的成本增加可能是无关紧要的。
只需选择与您具有的任何其他条件匹配的所有配置文件,然后在客户端过滤掉用户已经喜欢的任何配置文件。
首先,获取用户喜欢的所有配置文件:var likedUsers = firebase.firestore().collection('users')
.where('likedBy.C345','==',false)
然后获取所有用户,对照第一个列表进行检查并丢弃所有匹配的内容。var allUsers = firebase.firestore().collection('users').get()
根据规模,您可能需要优化第一步,例如每次用户喜欢某人时,请为该用户针对自己喜欢的每个人更新一个文档中的数组。这样,您只需为第一步获取一个文档。var likedUsers = firebase.firestore().collection('likedUsers')
.doc('C345').get()
由于此查询确实按结果集的大小进行缩放(通过将结果集定义为数据集),因此Cloud Firestore可以回答该问题,而无需进行大量隐藏的不可缩放的工作。不可扩展部分留给您优化(上面有2个示例)。
欠扫描
在“欠扫描”选项中,您基本上是在以准确性为代价来获得更窄(因此价格更便宜)的结果集。
这种方法比较复杂,因此,如果出于某种原因,喜欢的比率与不喜欢的比率不像我在“过扫描”选项中所怀疑的那样,您可能只想考虑使用它。
基本想法是,如果您确实喜欢某人,则将其排除在外,并接受可能还会排除您尚未喜欢的某人的折衷方案-是的,基本上是Bloom filter。
在每个用户配置文件中,存储从true
到false
的0
/ m
值的映射(稍后将介绍m
),其中所有内容最初都设置为false
。
当用户喜欢该配置文件时,请计算该用户ID的哈希值,以插入到Bloom过滤器中,并将映射中的所有这些位设置为true
。
因此,假设我们使用C345
将m = 4
散列为0110,则您的地图将如下所示:
likedBy: {
0: false,
1: true,
2: true,
3: false }
0
到
m
的任何位,查询它是否为false:
var usersRef = firebase.firestore().collection('users')
.where('likedBy.1','==',false)
false
的某个点上具有
true
值的任何人肯定不会被他们喜欢。
m = 1675
将误报率保持在20%或更少。
m
,
for example here。
m
小于
8000
以避免运行)纳入Cloud Firestore中的每个文档索引限制)。
x%
设置为true以上的任何配置文件都会将
popular
标志设置为true。对流行标志上的每个人进行过扫描,并将其编织到“欠扫描”结果中(请记住进行丢弃设置)。
关于node.js - Firestore,如何构建“likedBy”查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49010760/
我在解决如何最好地构造我的(非常简单的)Firestore应用程序时遇到一些麻烦。我有一组这样的用户: users: { 'A123': { 'name':'Adam' },
我是一名优秀的程序员,十分优秀!