Firebase Firestore中可以进行复杂的复合查询吗?

yb3bgrhw  于 2023-01-14  发布在  其他
关注(0)|答案(3)|浏览(200)

我正在使用Firebase作为应用程序的后端,我需要创建一个匹配系统,使用一些标准将用户与当前用户进行匹配。
由于数据库可能包含大量用户,我希望避免从数据库中检索每个用户并手动过滤,以避免加载时间。
每个用户文档中存储的相关数据包括:date of birth(时间戳)、an array of user interests(字符串列表)、an array of already matched user ids(字符串列表)和user's gender preference(字符串F或M)。
它应根据以下查询查找用户数据:
1.出生日期必须最多比当前用户早或早2年

  1. interests数组必须至少包含当前用户的一个共同兴趣
    1.性别必须与当前用户的性别首选项匹配
    1.用户ID不能已在当前用户的“已匹配用户ID”列表中
    在检索到匹配用户列表后,我还希望它按照与当前用户的共同兴趣进行排序,这样最匹配的用户会显示在最前面。
    到目前为止,我唯一的解决方案是从数据库中随机获取50个用户,检查他们是否匹配(在代码中),如果找到的匹配少于6个,则继续重复,直到找到至少6个匹配。如果在整个数据库中没有找到匹配的用户,则简单地获取6个随机用户。
    我知道Firebase在查询和过滤数据方面的限制,所以我想知道这样的事情是否可能?
sh7euo9m

sh7euo9m1#

这种类型的关系数据不太适合NoSQL文档数据库(特别是当根据您以前是否见过结果来取消结果资格时),但现在我们先忽略这一点。
结合条件1,2和3是可能的。但是您需要在请求数据的一方根据条件4取消结果资格(例如,在客户端/后端- Firestore的索引无法处理它)。这是因为条件2和4都依赖于数据数组,并且您被限制为一次只能查询一个。由于用户匹配的数量相对于平台上的用户数量可能较低,因此条件4更适合基于代码的过滤。
注意:由于用户的约会档案的敏感性,档案应只包含用户的ID和档案数据(没有电子邮件或电话号码)。此外,您应考虑通过受监管的后端服务,如云功能,而不是仅仅使他们直接客户端可读,这可能会导致平台滥用。

const profilesColRef = collection('profiles');

const potentialMatchesQuery = query(
  profilesColRef,
  where('dob', '>=', '1996-01-01'), // use YYYY-MM-DD format (numeric/date values can get messy with timezones if not careful)
  where('dob', '<=', '2000-01-01'),
  where('gender', '==', 'M'),
  where('interests', 'array-contains-any', userInterestArray), // supports up to 10 per query! Split into chunks of 10 and merge results for more interests
  limit(50)
);

const querySnapshot = await getDocs(potentialMatchesQuery)
const results = querySnapshot.docs
  .filter((doc) => !userPreviousMatches.includes(doc.id))
  .map((doc) => ({ id: doc.id, ...doc.data() }) // expand to basic JavaScript object

// results now contains up to 50 matches
// return results to client/use results
dsekswqp

dsekswqp2#

您是否将Firestore与Firebase一起使用?
在那里,您可以直接在firebase上使用查询。

Query query = users.whereEqualTo("user_interest", "sports");

或者像这样使用“in”运算符:

Query query = users.whereIn("user_interest", Arrays.asList("sports", "books"));

您不必以这种方式获取所有用户。
查看此链接以了解更多信息:https://firebase.google.com/docs/firestore/query-data/queries?hl=en

jxct1oxe

jxct1oxe3#

getSomeData(var: string) {
 const sitesRef = collection(this.firestore, 'YOUR-COLLECTION-NAME');
 const q = query(sitesRef,
                where("site_sub_type", "==", "somesite"),
                where("state", "==", var),
                orderBy("site_id")
        );
    return collectionData(q, { idField: 'id'}) as Observable<ksa_Site[]>;
}

这是可行的,你可以在where子句中分层,然后在你的组件ts文件中调用它。

this.SiteService.getSomeData(this.var).subscribe(res => {
     this.ARRAY_OF_VALUES = res; 
     this.cd.detectChanges();
});

请记住,您需要此值ARRAY_OF_VALUES:您的数据结构[] = [];

相关问题