简体   繁体   English

在Firebase中,如何查询最近的10个子节点?

[英]In Firebase, how can I query the most recent 10 child nodes?

I'm using childByAutoId() to generate my children. 我正在使用childByAutoId()来生成我的孩子。 Each child looks like: 每个孩子看起来像:

{
    user_id: 1
}

I'd like to get the last 10 most recently added, sorted by time DESC. 我希望得到最近添加的10个,按时间DESC排序。 What's the easiest way to do this? 最简单的方法是什么?

The answer is that you need to use a bit of reverse logic, and also store a timestamp key:value pair within each node as a negative value. 答案是您需要使用一些反向逻辑,并将每个节点中的时间戳键:值对存储为负值。 I omitted the user_id: 1 to keep the answer cleaner. 我省略了user_id:1以保持答案更清晰。

Here's the Firebase structure 这是Firebase结构

"test" : {
    "-KFUR91fso4dEKnm3RIF" : {
      "timestamp" : -1.46081635550362E12
    },
    "-KFUR9YH5QSCTRWEzZLr" : {
      "timestamp" : -1.460816357590991E12
    },
    "-KFURA4H60DbQ1MbrFC1" : {
      "timestamp" : -1.460816359767055E12
    },
    "-KFURAh15i-sWD47RFka" : {
      "timestamp" : -1.460816362311195E12
    },
    "-KFURBHuE7Z5ZvkY9mlS" : {
      "timestamp" : -1.460816364735218E12
    }
  }

and here's how that's written out to Firebase; 以及这是如何写到Firebase的; I just used a IBAction for a button to write out a few nodes: 我只是使用IBAction按钮来写出几个节点:

let testRef = self.myRootRef.childByAppendingPath("test")

let keyRef = testRef.childByAutoId()

let nodeRef = keyRef.childByAppendingPath("timestamp")

let t1 = Timestamp

nodeRef.setValue( 0 - t1) //note the negative value

and the code to read it in 和读取它的代码

    let ref = self.myRootRef.childByAppendingPath("test")
    ref.queryOrderedByChild("timestamp").queryLimitedToFirst(3).observeEventType(.ChildAdded, withBlock: { snapshot in
        print("The key: \(snapshot.key)") //the key
    })

and I declared a little function to return the current Timestamp 我声明了一个小函数来返回当前的时间戳

var Timestamp: NSTimeInterval {
    return NSDate().timeIntervalSince1970 * 1000
}

and the output 和输出

The key: -KFURBHuE7Z5ZvkY9mlS
The key: -KFURAh15i-sWD47RFka
The key: -KFURA4H60DbQ1MbrFC1

As you can see, they are in reverse order. 如您所见,它们的顺序相反。

Things to note: 注意事项:

  1. Writing out your timestamp as negative values 将时间戳写为负值
  2. When reading in use .queryLimitedToFirst instead of last. 在阅读时使用.queryLimitedToFirst而不是last。

On that note, you can also just read the data as usual and add it to an Array then then sort the array descending. 在这方面,您也可以像往常一样读取数据并将其添加到数组中,然后对数组进行降序排序。 That puts more effort on the client and if you have 10,000 nodes may not be a good solution. 这会给客户带来更多的努力,如果你拥有10,000个节点可能不是一个好的解决方案。

I'm assuming your data actually looks like this: 我假设你的数据实际上是这样的:

someDataSet: {
    longUID-1: {
        timeCreated: 9999999999, // (seconds since the javascript epoch)
        user_id: 1
    },
    longUID-2: {
        timeCreated: 1111111111,
        user_id: 2
    },
    longUID-3: {
        timeCreated: 3141592653,
        user_id: 3
    }
}

You could automate that by calling Firebase.push({user_id: ###, timeCreated: ###}) multiple times in a for loop or any other method. 您可以通过在for循环或任何其他方法中多次调用Firebase.push({user_id: ###, timeCreated: ###})来自动执行此操作。 Maybe you're adding news stories to a webpage, but you only want your user to see the most current stories--- IDK. 也许你是在网页上添加新闻报道,但你只希望你的用户看到最新的故事--- IDK。 But the answer to your question is to use Firebase's ref.orderByChild() and ref.limitToLast() . 但问题的答案是使用Firebase的ref.orderByChild()ref.limitToLast()

var ref = new Firebase("<YOUR-FIREBASE-URL>.firebaseio.com/someDataSet"); 
    //the "/someDataSet" comes from the arbitrary name that I used up above

var sortedRef = ref.orderByChild('timeCreated');
    //sort them by timeCreated, ascending

sortedRef.limitToLast(2).on("child_added", function(snapshot){
    var data = snapshot.val();

    console.log(data);

    /* do something else with the data */
});

//The console would look like this

// Object {timeCreated: 9999999999, user_id: 1}
// Object {timeCreated: 3141592653, user_id: 3}

This happened because the program took the child with the greatest timeCreated value first and then the second greatest (value) second... Also note, the longUID means nothing when you sort them by child and neither do the other values (user_id in this case) 之所以发生这种情况,是因为该程序首先使用timeCreated值最大的子timeCreated ,然后是第二个(值)第二个...另外请注意,当您按子进行排序时,longUID没有任何意义,其他值也没有(在这种情况下为user_id) )

Here is the documentation for: 这是以下文档:

The code: ref.queryOrderedByKey().queryLimitedToLast(10) can be used for getting the most recent 10 data. 代码: ref.queryOrderedByKey().queryLimitedToLast(10)可用于获取最新的10个数据。 However, this is an ascending order by default. 但是,默认情况下这是升序。

Alternatively, you can order your data via 或者,您可以通过订购数据

ref.orderByChild("id").on("child_added", function(snapshot) {
  console.log(snapshot.key());
});

This also presents an ascending order by default. 默认情况下,这也会显示升序。 To change it into descending order is little bit tricky. 将其更改为降序有点棘手。 What I would suggest it to multiply ids by -1 as shown below and then sort them. 我建议将ID乘以-1,如下所示,然后对它们进行排序。

var ref= new Firebase("your data");
ref.once("value", function(allDataSnapshot) {
  allDataSnapshot.forEach(function(dataSnapshot) {
    var updatedkey = -1 * dataSnapshot.key();
    ref.update({ element: { id: updatedkey}});
  });
});

This two SO page might be useful for you also, please check: 这两个SO页面也可能对您有用,请检查:

How to delete all but most recent X children in a Firebase node? 如何删除Firebase节点中除最近X个孩子以外的所有子项?

firebaseArray descending order? firebaseArray降序排列?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Swift中的多个节点中观察Firebase子值的变化? - How can I observe Firebase child value changes in multiple nodes in Swift? 如何使用Firebase(Swift)中的安全规则限制子节点 - How can i limit child nodes using security rules in Firebase (Swift) 如何从Firebase订购从最新到最旧的图像? - How to order fetched images from Firebase, from most recent to oldest? 如何在定义的时间间隔内每天从HealthKit数据中获取最新的体重条目 - How can I fetch the most recent weight entry from HealthKit data for each Day in a defined time interval 在Firebase上查询不会在云上带来最新值,而是在设备上本地 - Query over firebase doesn't bring most recent values on cloud, but local on device 来自2个节点的Firebase查询 - Firebase query from 2 nodes 如何使用用户输入为Firebase中的孩子命名? - How can I use user input to name a child in Firebase? 如何从Firebase数据库中的许多子项中检索数据 - How can I retrieve data from many child in firebase database iOS-如何从Firebase中的多个父节点中删除孩子? - iOS - How To Remove Child From Multiple Parent Nodes In Firebase? 我可以在Xcode beta中开发,然后从最新的Xcode GM提交吗? - Can I develop in Xcode beta, then submit from the most recent Xcode GM?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM