2017-08-01 57 views
1

我正在开发一个应用程序,如出租车预订和在Firebase上存储数据。如何在Swift中的Firebase查询中应用多个过滤器?

但是,在从Firebase查询RideDetail(History)的数据时,我面临问题。

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

我的火力地堡数据结构:

{ 
    "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 
    } 
} 

我想第一个10条具体的“CUSTOMER_ID”我通过查询orderedBy“payment_time”。我也想做同样的分页。即在第二个查询调用中,它必须返回11-20条记录等等。

+0

请将您的firebase结构作为文本发布,而不是图片。图像不可搜索,如果我们需要在答案中使用它,必须重新输入。你能澄清你的查询吗?你的预期结果是什么? – Jay

+0

@Jay请再次检查我已编辑的问题。 – DJ1

+0

这个问题还不清楚;是您希望特定客户拥有特定付款类型的X个记录的数据集?如果这是正确的,那么您的'我想要的'响应不匹配,因为它是同一个客户的两种不同的付款类型。也许这是别的吗? * OrderBy“payment_time”和“customer_id”等于“value”。*不清楚。您是否希望按pay_type排序返回的值,并且要返回的值是customer_id = value? – Jay

回答

1

问题和意见有一些不同的标准,但让我以高级别解决它;

第一个答案是: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乘坐的数组。

然后查询所有用于cust id 4的游乐设施。我们有一个循环来显示什么retreived无序,然后这个小宝石

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" 
    } 
    }, 

,然后一些代码在卡斯特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中非常高代码级的字符 - 因为它包含所有前面的字符。

+0

谢谢。您的解决方案适用于我。非常感谢您的帮助。 – DJ1

0

有两种可能对你的要求工作的基本方法:

  1. 构造查询,通过payment_time订单,限制为仅包含前10条记录,然后持有到10日记录,以便参考您可以使用queryStartingAtValue过滤器进行后续分页呼叫。

  2. 使用数据库触发器设置Firebase云端函数,并监听payment_time节点,这样每当您用数据库中的某个值更新空数据库时,就会转换数据以便它以这种方式进行组织在这里消费满足您的需求微不足道。例如 - 我将以如下方式组织新数据:customer_ride_details/{{customer_id}}/{{ride_id}}。并且,由于您在使用时间戳替换payment_time空字符串时触发了该功能。钥匙应该已经订购,供您消费。您仍然需要像处理选项1一样管理分页。

+0

您能否详细解释结构或查询。 – DJ1

相关问题