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

时间:2016-04-13 05:36:15

标签: ios firebase

我使用childByAutoId()生成我的孩子。每个孩子看起来像:

{
    user_id: 1
}

我希望获得最近添加的10个,按时间DESC排序。最简单的方法是什么?

3 个答案:

答案 0 :(得分:18)

答案是您需要使用一些反向逻辑,并将每个节点中的时间戳键:值对存储为负值。我省略了user_id:1以保持答案更清晰。

这是Firebase结构

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

以及这是如何写入Firebase的;我只是使用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

以及在

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

我宣布了一个小函数来返回当前的时间戳

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

和输出

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

如您所见,它们的顺序相反。

注意事项:

  1. 将时间戳写为负值
  2. 在阅读时使用.queryLimitedToFirst而不是last。
  3. 在那个注释中,您也可以像往常一样读取数据并将其添加到数组中,然后对数组进行降序排序。这会给客户带来更多的努力,如果你拥有10,000个节点可能不是一个好的解决方案。

答案 1 :(得分:2)

我假设你的数据实际上是这样的:

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

您可以通过在for循环或任何其他方法中多次调用Firebase.push({user_id: ###, timeCreated: ###})来自动执行此操作。也许你是在网页上添加新闻报道,但你只希望你的用户看到最新的故事--- IDK。但问题的答案是使用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}

之所以发生这种情况,是因为该程序首先使用timeCreated值最大的孩子,然后是第二大(值)第二... 另请注意,longUID在按孩子排序时没有任何意义,其他值也没有(在这种情况下为user_id)

以下是:

的文档

答案 2 :(得分:2)

代码:ref.queryOrderedByKey().queryLimitedToLast(10)可用于获取最新的10个数据。但是,默认情况下这是升序。

或者,您可以通过

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

默认情况下,这也会显示升序。将其更改为降序有点棘手。我建议将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}});
  });
});

这两个SO页面也可能对您有用,请检查:

How to delete all but most recent X children in a Firebase node?

firebaseArray descending order?