如何在Swift中的Firebase查询中应用多个过滤器? [英] How to apply multiple filter in Firebase query in Swift?

查看:222
本文介绍了如何在Swift中的Firebase查询中应用多个过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

但是,从Firebase查询RideDetail(History)的数据时,我面临问题。我试图开发一个应用程序,如出租车预订和在Firebase上存储数据。



我想为分页格式的特定customer_id获取ride_detail。



我的Firebase DataStructure: p

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ tstebwLlf4OCRdWhNKO9XCO08xY2,
destination_address:New Ranip \ NewNew Ranip \\\
Ahmedab​​ad\\\
Gujarat 380081\\\
India,
destination_lang:72.55924470000001,
destination_latg:23.0930152,
discount:10%,
driver_id:cIyZQIJ7tsdvF1a9KpRrKucF2o62,
drop_time:2017-07-29 09:12:21 +0000,
票价:13.16卢比,
payment_time:150149034812771,
pickup pickup时间:2017-07-29 09:10:38 +0000,
priceperkm:10.00 R ,
ride_confirm_time:2017-07-29 09:06:21 +0000,
source_address:Vastrapur \\\
Vastrapur\\\
Ahmedab​​ad\Gujarat\\\
India ,
SOURCE_LANG:72.5293244,
source_latg:23.0350073,
税: 10%
},
RH0oZ0Ypbkur3wJM3HMvM150147833457957:{
CUSTOMER_ID: aYQFbwLlf4OCRdWhNKO9XCO08xY2,
的destination_address:纳萨诺瓦公园假日酒店及度假村私人Limted\\\
No 1\\\
Sector 10\\\
CBD Belapur\\\
Wadala West\\\
Wadala\\\
Mumbai\\ \
Maharashtra 400614\\\
India,
destination_lang:72.8561644,
destination_latg:19.0176147,
打折:0,
driver_id: cIyZQIJ7tsdvF1a9KpRrKucF2o62
drop_time:,
票价:0,
payment_time:150149034812772,
pickup pickup时间:,
priceperkm: 0,
ride_confirm_time:2017-07-31 05:18:54 +0000,
sour ce_address:Smokin乔的新鲜比萨店#2#\\ n3 \ nGround Floor\Abbhiman II \\ source_lang:72.8561644,
source_latg:19.0176147,
tax:0
}
}
}



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



  {
的RH0oZ0Ypbkur3wJM3HMvM150147833457957:{
的CUSTOMER_ID: aYQFbwLlf4OCRdWhNKO9XCO08xY2,
的destination_address: 纳萨诺瓦公园假日酒店及度假村私人Limted\\\
No 1\\\
Sector 10\\\
CBD Belapur\\\
Wadala West\\\
Wadala\\\
Mumbai\\\
Maharashtra 400614\\\
India,
destination_lang:72.8561644,
destination_latg:19.0176147,
打折:0,
driver_id: cIyZQIJ7tsdvF1a9KpRrKucF2o62,
drop_time: ,
票价:0,
payment_type:150149034812772,
pickup pickup时间:,
priceperkm:0,
ride_confirm_time:2017 -07-31 05:18:54 +0000,
source_address:Smokin Joe的新鲜比萨店#2#\\ n3 \ nGround Floor \\\
Abhiman II \Wadala West \\\
Thane West \\\
Mumbai \\\
Maharashtra 400602\\\
India,
source_lang:72.8561644,
source_latg:19.0176147,
tax:0
},
1trcf0Ypbkur3wJM3HMvM150147833457957:{
customer_id:aYQFbwLlf4OCRdWhNKO9XCO08xY2,
destination_address:萨诺瓦公园广场酒店和度假村私人有限公司\ 1号区域nWadala West \Wadala\\\
Mumbai\\\
Maharashtra 400614\\\
India,
destination_lang:72.8561644,
destination_latg:19.0176147,
discount:0,
driver_id:cIyZQIJ7tsdvF1a9KpRrKucF2o62,
drop_time:,
票价:0,
payment_type:150149034812778,
pickup pickup时间:,
priceperkm:0,
ride_confirm_time:2017-07-31 05:18:54 +0000,
source_address:Smokin Joe的新鲜比萨店\ 2号店\\\\\\\\\ II \Wadala West \\\
Thane West \\\
Mumbai\\\
Maharashtra 400602\\\
India,
source_lang:72.8561644,
source_latg:19.0176147,
tax:0




$ b $ p
$ b我想要特定的customer_id的前10条记录我通过查询orderedBypayment_time。我也想做同样的分页。即在第二个查询调用中,它必须返回11-20条记录等。 解决方案

问题和评论有一些不同的标准但让我来解决它的高水平;

第一个答案是:Firebase不能被查询一个孩子的价值,然后由另一个排序。



简单的查询函数表示:

pre $ let $ query = ridesRef.queryOrdered(byChild :cust_id)。q​​ueryEqual(toValue:cust id 4)

要完成这个任务,查询您想要的子数据,在这种情况下,所有客户ID为4个节点,然后在代码中进行订购。这里是一个例子

  class RideClass {
var key =
var cust_id =
$ var $ pay

$ b $ self $ key $ key $ b $ self $ key $ $ b self.pay_time = pay_time



var rideArray = [RideClass]()

func populateRideArray(){
let usersRef = self.ref.child(ride_details)
let query = usersRef.queryOrdered(byChild:cust_id)。q​​ueryEqual(toValue:cust id 4)
query.observeSingleEvent :.value,其中:{snapshot in
for 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,p ay_time:payTime)
self.rideArray.append(ride)
}

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

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

用于self.rideArray {//排序示例
print(ride.pay_time)
}
})$ b $在这个例子中,我们创建了一个RideClass,其中存储了一些关于乘坐的信息,然后是一个RideClass。然后查询所有用于cust_id4的游乐设施。我们有一个循环来显示什么是retreived未分类和那么这个小宝石

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

通过pay_time排序数据,这回答了问题。假设尽管有100,000个乘坐子节点。加载所有这些数据并在代码中进行排序可能会使记忆更具挑战性。你做什么?



我们利用复合值;以及cust_id和pay_time的子节点,我们还包括id_time。这里有一个可能的结构:

$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $' :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_\\\\ )
query.observeSingleEvent(of:.value,其中:$ snapshot中的快照$ b $为快照.children中的子项{
let snap = child as! DataSnapshot
让dict = snap.value as! [String:Any]
let key = snap.key
let custId = dict [cust_id] as! String
let payTime = dict [pay_time] as!字符串
让ride = RideClass(key:key,cust_id:custId,pay_time:payTime)
self.rideArray.append(ride)
}

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

有两点需要注意:

必须迭代快照才能维护子序列

\\\是Unicode中一个非常高的代码级别的字符 - 因为它包含了所有前面的字符。


I am trying developing an application like Taxi booking and storing data on Firebase.

But, I am facing problem while querying data for RideDetail(History) from Firebase.

I want to fetch ride_detail for specific "customer_id" in pagination form.

My 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
    }
  }
}

Here "payment_time" is timestamp when payment done.

And the response I want is like:

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

I want first 10 records for specific "customer_id" that I pass in query orderedBy "payment_time". Also I want to do pagination for the same. i.e. in second query call, it must return 11-20 records and so on.

解决方案

The question and comments have some different criteria but let me address it at a high level;

The first answer is: Firebase cannot be queried for the value of one child and then ordered by another.

The simple query function expresses that:

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

To accomplish that task, query for the child data you want, in this case all customer id 4 nodes, and then order in code. Here's an example

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)
        }
    })
}

In this example, we create a RideClass which stores some info about the ride, and then an array of rides which could be used as a tableView dataSource.

Then query for all rides that are for cust id 4. We have a loop to show what was retreived unsorted and then this little gem

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

which sorts the ride array in place by pay_time, which answers the question.

Suppose though, there are 100,000 ride child nodes. Loading in all of that data and sorting in code could be challenging memory wise. What do you do?

We leverage a compound value; along with the child nodes of cust_id and pay_time, we also include id_time. Here's a possible structure:

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

and then some code to read in the cust id 4 nodes in the correct order

    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)
        }
    })

Two things to note:

The snapshot must be iterated over to maintain the child sequence

"\uf8ff" is a character at a very high code level in Unicode - because of that it encompasses all of the preceeding characters.

这篇关于如何在Swift中的Firebase查询中应用多个过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆