Firebase Firestore - 或查询替代方案

时间:2017-10-18 08:24:04

标签: swift firebase google-cloud-firestore

在这个问题Firebase Firestore - OR query中,他们说没有OR查询。这意味着我无法轻松查询具有我之前获得的数组ID的项目。

// What I want
documentRef
    .whereField("itemId", isEqualTo: "id1")
    .orWhereField("itemId", isEqualTo: "id3")

// or
documentRef
    .whereField("itemId", in: idArray)

由于这不起作用,查询我的数据的选项会更好吗?

  1. 获取所有数据并在本地查看
  2. 我可以获取所有记录,只检查设备上的ID,但问题是它最多可以有1000条记录,而用户可能只需要其中的三条记录。

    1. 对所有项目执行单独查询
    2. 我可以为用户需要的每个项目执行查询whereField("itemId", isEqualTo: "id")。如果用户只需要一些项目,但用户可能需要所有项目,并且此解决方案将比第一个项目慢很多,那么这将是很好的。 (除非你可以批量阅读)

      1. 移动数据
      2. 我想我可以将购买的数据移动到Item集合中:Items/itemid/PurchasedBy/uid但是我想要检索用户已购买的项目,而我不知道如何通过内部字段查询项目嵌套的集合。我也不知道这是否是数据的正确位置。

        我的数据:

        Users/uid/PurchasedItems/itemid
        
            payedInMoney: "$0.00"
            payedInCoins: "100"
            itemId: "itemid"
            timeStamp: timestamp
        
        Items/itemid
        
            itemId: "itemid"
            // Other item info
        

        编辑:

        我做了第一个选项,因为这就是我在RTDB上的做法,但即使持续使用addSnapshotListener,Firestore也不能接近RTDB实现的速度。我计算时间,看起来Firestore的速度至少是RTDB的4倍(两者都启用了持久性)。

        // iPad 5 (2017) - iOS 11
        RTDB:  50-100ms
        FST:  350-450ms
        
        // iPad Air (2014) - iOS 10
        RTDB: 100-150ms
        FST:  700-850ms
        
        // iPad Mini (2012) - iOS 9
        RTDB: 150-200ms
        FST:  2900-3200ms
        

        编辑2:

        决定坚持使用RTDB,直到Firestore上的持久性确实有效。

        编辑3:

        接受的答案解决了这个问题中的问题,即使它没有解决所有我的问题,也可能有助于其他人。

        在仅使用Firestore的一个查询进行测试后,结果仍然比在RTDB中执行嵌套查询需要更长的时间,因此我现在将坚持我的决定。

2 个答案:

答案 0 :(得分:1)

这似乎是复制某些项目数据的好例子。我假设某些项目属性如“name”是不可变的,因此可以存储在 sudo apt-get autoremove sudo apt-get autoclean sudo apt-get update 子集中,而不必担心将来的更新。

因此,如果您将部分数据添加到PurchasedItems

PurchasedItems

然后,您将有足够的信息在单个查询中显示用户购买商品的列表,而无需按ID查找每个商品。

答案 1 :(得分:0)

您可以使用rxjs组合Observable;

orQuery(){

    const $one = this.afs.collection("items", ref => ref.where("itemId","==","1")).valueChanges();
    const $two = this.afs.collection("items", ref => ref.where("itemId","==","3")).valueChanges();

    return combineLatest($one,$two).pipe(
        map(([one, two]) => [...one, ...two])
    )
}

getOr(){
    this.orQuery().subscribe(data => console.log(data))
}