【问题标题】:Get a single document by foreign key in using RxJs and AngularFirestore使用 RxJs 和 AngularFirestore 通过外键获取单个文档
【发布时间】:2018-08-14 05:50:45
【问题描述】:

我编写了一个如下所示的查询:

getPaymentByBookingId(id: string): Observable<Payment> {
    return this.afs.collection<Payment>('payments', ref => ref.where('bookingId', '==', id).limit(1))
        .valueChanges()
        .pipe(
            flatMap(array => from(array)),
            first()
        );
}

Payment 对象具有对Booking id 的唯一引用。我想查找给定 ID 的付款。

这似乎是一个相当复杂的方式来纠正这个查询。

有没有更简单的方法来做到这一点 - 包括这里是否有代码异味使这变得困难?

【问题讨论】:

    标签: rxjs angularfire2


    【解决方案1】:

    您可以仅使用 Javascript 原生数组 API .find() 来完成,它会为您节省几行代码:

    getPaymentByBookingId(id: string): Observable<Payment> {
        return this.afs.collection<Payment>('payments')
            .valueChanges()
            .pipe(
                map(allPayments=>allPayments.find(payment=>payment.bookingId === id))
            );
    }
    

    或者您可以使用.first() 运算符并提供其首次满足条件:

    getPaymentByBookingId(id: string): Observable<Payment> {
        return this.afs.collection<Payment>('payments')
            .valueChanges()
            .pipe(
                flatMap(array => from(array)),
                first(eachPayment => eachPayment.bookingId === id)
            );
    }
    

    请注意,过滤在幕后的工作方式存在根本差异。我个人更喜欢 Javascript 的原生函数,因为我觉得使用 from(array) 转换 observable 有点多余,只是为了让它一一发出数组序列。

    还请注意,通过执行ref =&gt; ref.where('bookingId', '==', id),您的过滤实际上发生在查询级别(也就是不在客户端)。如果你确信payments检索的数量不会很大,那么让客户端做过滤就可以了;否则最好将处理部分卸载到服务器。

    【讨论】:

    • 这不会将查询从(可能)firebase 服务器移动到 JS 客户端吗?这意味着它需要下载所有付款才能找到正确的付款?
    • @MarkHughes 是的,你是对的。我想我会编辑并使其更清晰。
    • 我觉得你的回答从根本上是有问题的——它真的不适合拉入整个集合然后过滤它。
    【解决方案2】:

    稍微简单一点的是:

    getPaymentByBookingId(id: string): Observable<Payment> {
        return this.afs.collection<Payment>('payments', ref => ref.where('bookingId', '==', id).limit(1))
            .valueChanges()
            .pipe(
                map(array => array[0]),
            );
    }
    

    如果没有找到付款,这将返回undefined

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      • 2018-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      相关资源
      最近更新 更多