当前位置: 首页 > 面试题库 >

如何在Swift的Firebase查询中应用多个过滤器?

鞠宏恺
2023-03-14
问题内容

我正在尝试开发出租车预订等应用程序并将数据存储在Firebase上。

但是,从Firebase查询RideDetail(History)数据时遇到问题。

我想以分页形式获取ride_detail以获得特定的“ customer_id”。

我的Firebase DataStructure:

{
  "ride_details": {
    "NuEoP2WNPwigsbY1FQy9M150131918189233": {
      "customer_id": "tstebwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "New Ranip\nNew Ranip\nAhmedabad\nGujarat 380081\nIndia",
      "destination_lang": 72.55924470000001,
      "destination_latg": 23.0930152,
      "discount": "10%",
      "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62",
      "drop_time": "2017-07-29 09:12:21 +0000",
      "fare": "13.16 Rs.",
      "payment_time": 150149034812771,
      "pickup_time": "2017-07-29 09:10:38 +0000",
      "priceperkm": "10.00 Rs.",
      "ride_confirm_time": "2017-07-29 09:06:21 +0000",
      "source_address": "Vastrapur\nVastrapur\nAhmedabad\nGujarat\nIndia",
      "source_lang": 72.5293244,
      "source_latg": 23.0350073,
      "tax": "10%"
    },
    "RH0oZ0Ypbkur3wJM3HMvM150147833457957": {
      "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted\nNo 1\nSector 10\nCBD Belapur\nWadala West\nWadala\nMumbai\nMaharashtra 400614\nIndia",
      "destination_lang": 72.8561644,
      "destination_latg": 19.0176147,
      "discount": 0,
      "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62",
      "drop_time": "",
      "fare": 0,
      "payment_time": 150149034812772,
      "pickup_time": "",
      "priceperkm": 0,
      "ride_confirm_time": "2017-07-31 05:18:54 +0000",
      "source_address": "Smokin Joe's Fresh Pizza\nShop No. 2\n3\nGround Floor\nAbhiman II\nWadala West\nThane West\nMumbai\nMaharashtra 400602\nIndia",
      "source_lang": 72.8561644,
      "source_latg": 19.0176147,
      "tax": 0
    }
  }
}

这里的“ payment_time”是付款完成后的时间戳。

我想要的响应是:

{
    "RH0oZ0Ypbkur3wJM3HMvM150147833457957": {
      "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted\nNo 1\nSector 10\nCBD Belapur\nWadala West\nWadala\nMumbai\nMaharashtra 400614\nIndia",
      "destination_lang": 72.8561644,
      "destination_latg": 19.0176147,
      "discount": 0,
      "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62",
      "drop_time": "",
      "fare": 0,
      "payment_type": 150149034812772,
      "pickup_time": "",
      "priceperkm": 0,
      "ride_confirm_time": "2017-07-31 05:18:54 +0000",
      "source_address": "Smokin Joe's Fresh Pizza\nShop No. 2\n3\nGround Floor\nAbhiman II\nWadala West\nThane West\nMumbai\nMaharashtra 400602\nIndia",
      "source_lang": 72.8561644,
      "source_latg": 19.0176147,
      "tax": 0
    },
    "1trcf0Ypbkur3wJM3HMvM150147833457957": {
      "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted\nNo 1\nSector 10\nCBD Belapur\nWadala West\nWadala\nMumbai\nMaharashtra 400614\nIndia",
      "destination_lang": 72.8561644,
      "destination_latg": 19.0176147,
      "discount": 0,
      "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62",
      "drop_time": "",
      "fare": 0,
      "payment_type": 150149034812778,
      "pickup_time": "",
      "priceperkm": 0,
      "ride_confirm_time": "2017-07-31 05:18:54 +0000",
      "source_address": "Smokin Joe's Fresh Pizza\nShop No. 2\n3\nGround Floor\nAbhiman II\nWadala West\nThane West\nMumbai\nMaharashtra 400602\nIndia",
      "source_lang": 72.8561644,
      "source_latg": 19.0176147,
      "tax": 0
    } 
}

我希望我在orderedBy“ paying_time”查询中传递的特定“
customer_id”的前10条记录。我也想做分页。即在第二次查询调用中,它必须返回11-20条记录,依此类推。


问题答案:

这个问题和评论有一些不同的标准,但让我从高层次解决。

第一个答案是:无法查询Firebase的一个孩子的值,然后再排序。

简单查询功能表示:

let query = ridesRef.queryOrdered(byChild: "cust_id").queryEqual(toValue: "cust id 4")

要完成该任务,请查询所需的子数据(在本例中为所有客户id 4个节点),然后按代码订购。这是一个例子

class RideClass {
    var key = ""
    var cust_id = ""
    var pay_time = ""

    init(key: String, cust_id: String, pay_time: String) {
        self.key = key
        self.cust_id = cust_id
        self.pay_time = pay_time
    }
}

var rideArray = [RideClass]()

func populateRideArray() {
    let usersRef = self.ref.child("ride_details")
    let query = usersRef.queryOrdered(byChild: "cust_id").queryEqual(toValue: "cust id 4") 
    query.observeSingleEvent(of: .value, with: { snapshot in 
        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let dict = snap.value as! [String: Any]
            let key = snap.key
            let custId = dict["cust_id"] as! String
            let payTime = dict["pay_time"] as! String
            let ride = RideClass(key: key, cust_id: custId, pay_time: payTime)
            self.rideArray.append(ride)
        }

        for ride in self.rideArray {  //unsorted example
            print(ride.pay_time)
        }

        self.rideArray.sort { $0.pay_time < $1.pay_time } //sort

        for ride in self.rideArray {  //sorted example
            print(ride.pay_time)
        }
    })
}

在此示例中,我们创建了一个RideClass,其中存储了有关游乐设施的一些信息,然后存储了可以用作tableView数据源的游乐设施数组。

然后查询所有客户ID为4的游乐设施。我们有一个循环显示未分类的取回内容,然后显示这个小宝石

self.rideArray.sort { $0.pay_time < $1.pay_time }

它将按pay_time对行驶数组进行排序,从而回答了问题。

但是,假设有100,000个乘车子节点。加载所有这些数据并按代码进行排序可能对内存方面提出挑战。你是做什么?

我们利用复合价值;连同cust_id和pay_time的子节点,我们还包括id_time。这是一个可能的结构:

  "ride_details" : {
    "ride_0" : {
      "cust_id" : "cust id 4",
      "id_time" : "cust id 4_172200",
      "pay_time" : "172200"
    },
    "ride_1" : {
      "cust_id" : "cust id 2",
      "id_time" : "cust id 2_165500",
      "pay_time" : "165500"
    },
    "ride_2" : {
      "cust_id" : "cust id 1",
      "id_time" : "cust id 1_182300",
      "pay_time" : "182300"
    },
    "ride_3" : {
      "cust_id" : "cust id 3",
      "id_time" : "cust id 3_131800",
      "pay_time" : "131800"
    },
    "ride_4" : {
      "cust_id" : "cust id 4",
      "id_time" : "cust id 4_132200",
      "pay_time" : "132200"
    }
  },

然后按正确的顺序读取cust id 4节点中的一些代码

    let ridesRef = self.ref.child("ride_details")
    let query = ridesRef.queryOrdered(byChild: "id_time")
                        .queryStarting(atValue: "cust id 4_")
                        .queryEnding(atValue: "cust id 4_\\uf8ff")
    query.observeSingleEvent(of: .value, with: { snapshot in
        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let dict = snap.value as! [String: Any]
            let key = snap.key
            let custId = dict["cust_id"] as! String
            let payTime = dict["pay_time"] as! String
            let ride = RideClass(key: key, cust_id: custId, pay_time: payTime)
            self.rideArray.append(ride)
        }

        for ride in self.rideArray {  //unsorted example
            print(ride.pay_time)
        }
    })

有两件事要注意:

必须迭代快照以维护子序列

“ \ uf8ff”是Unicode中很高代码级别的字符-因为它包含所有前面的字符。



 类似资料:
  • 我想获得如下数据 类别=“cat”和级别=“1” 这是我的密码 这是wrok,但如何在firbase中使用两个条件,我尝试两个,但它给出错误java.lang.IllegalArgumentException:您不能合并多个orderBy调用!

  • 问题内容: 基本上,我有一个名为的结构,主题包含,以及一个标志(有关说明,请参见下面的屏幕截图)。 在应用程序中,我想过滤数据,仅显示具有的主题。 这就是我想要做的: 但这是行不通的。我应该如何处理?在此先感谢您的帮助。 问题答案: 您那里有一些小错误。总体来说还算不错,但是结合起来它们将永远无法正常工作: 调用任何方法都将返回一个新对象 您需要先过滤其价值 您需要遍历结果 结合这些: 我们会定期

  • 问题内容: 我想找到离我最近的用户。(例如,最长5公里)我的节点在Firebase数据库中,如下所示, 有什么办法可以让这个半径范围内的确切用户。否则,我应该使用方法检查每个用户的最近位置或不向我显示。 问题答案: 我强烈建议您使用Geofire这样的工具。 要进行设置,您的数据结构将略有变化。您仍然可以将lat / lng存储在用户上,但是您还将创建一个名为以下内​​容的新Firebase表 您

  • 问题内容: 我必须通过一个映射过滤一个对象集合,该映射包含对象字段名称和字段值的键值对。我试图通过stream()。filter()应用所有过滤器。 对象实际上是JSON,因此Map保留了其变量的名称以及它们必须包含的值才能被接受,但是出于简单性的原因,并且由于它与问题无关,因此我编写了一个简单的Testclass来模拟行为: 到目前为止我尝试过的是: 我尝试将Map的forEach放在首位,并将

  • 我必须通过一个映射过滤对象集合,该映射包含对象字段名和字段值的键值对。我正在尝试按stream()应用所有过滤器。过滤器()。 对象实际上是JSON,因此映射包含其变量的名称以及它们必须包含的值,以便被接受,但出于简单的原因,并且由于与问题无关,我编写了一个简单的Testclass来模拟行为: 到目前为止我所尝试的: 我试着将地图的每个部分放在第一位,将集合的流放在第一位,但这两种解决方案都没有按

  • 问题内容: 我已经在Elasticsearch之上构建了一个Web应用程序。我想使用Java进行多重过滤。 Elasticsearch查询: 我想过滤查询,以便它应该在具有两个不同值(例如“ xyz”和“ abc”)的同一字段上进行过滤 现在,我已经为单个过滤器编写了Java程序。 如何在同一字段上为多个值过滤查询? 编辑 : 实际上,在我的Web应用程序中,我将集合的值提取为: 收藏是我的Ela