2017-08-12 101 views
0

我有以下查詢,以獲得最新的16篇自上次獲取:火力地堡JS:startAt,orderByChild和limitToLast

db.ref("articles).startAt(null, "last_fetched_key").orderByChild("published").limitToLast(16); 

所以應該在上一篇文章中我已經開始,然後命令那些由子鍵「發佈」,然後限制這些結果爲16.

只要我不做orderByChild(「發佈」),但如果我這樣做,我總是得到16項?

注:我看到在兩個的NodeJS(火力管理員5.1.0)和瀏覽器(火力-SDK 4.2.0)

實施例這種行爲:(見下文的數據例)

function countObj(obj) { var c=0; for (var k in obj) { c++; } return c; } 
function getLastKey(obj) { var lk=null; for (var k in obj) { lk = k; } return lk; } 

firebase.database().ref("articles/-KnLhC7S0wtNV17R-w2I") 
    .orderByChild("published") 
    .limitToLast(4) // limit 4, 
    .once("value", function(snap) { 

    var data = snap.val(); 

    console.log("#1 Results: "+ countObj(data.val())); // Results: 4 

    var lastKey = getLastKey(data); 

    // With .orderByChild("published") 
    // Should return 1 result because articles contains 4, we pass the 4th key to startAt() 
    firebase.database().ref("articles/-KnLhC7S0wtNV17R-w2I") 
     .startAt(null, lastKey) // use startAt 
     .orderByChild("published") 
     .limitToLast(4) 
     .once("value", function(snap) { 
     var data = snap.val(); 
     console.log("#2 Results: "+ countObj(data.val())); // Results: 4 
    }); 

    // Without .orderByChild("published") 
    // Returns 1 result because articles contains 4, we pass the 4th key to startAt() 
    firebase.database().ref("articles/-KnLhC7S0wtNV17R-w2I") 
     .startAt(null, lastKey) // use startAt 
     .limitToLast(4) 
     .once("value", function(snap) { 
     var data = snap.val(); 
     console.log("#3 Results: "+ countObj(data.val())); // Results: 1 
    }); 


    }); 

數據:

{ 
    "articles" : { 
    "-KnLhC7S0wtNV17R-w2I" : { 
     "1498230632000-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : { 
     "published" : 1498230632000 
     }, 
     "1498230632001-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : { 
     "published": 1000 
     }, 
     "1498230632002-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : { 
     "published": 900 
     }, 
     "1498230632003-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7" : { 
     "published": 1100 
     }, 
    } 
    } 
} 
+1

請共享重現問題所需的最低JSON(a沒有截圖)。您可以通過點擊[Firebase數據庫控制檯](https://console.firebase.google。)中的「導出JSON」鏈接來獲取此信息。COM /項目/ _ /數據庫/數據)。 –

+0

完成! (我希望我的示例代碼是足夠清晰的..在這裏輸入它所以沒有檢查.. :)) – REJH

回答

2

你似乎誤會如何參數startAt()工作。這裏有三個步驟:

  1. 首先數據按您的查詢指示進行排序。如果您沒有指定任何順序,則數據按優先級排序(對於您的案例中的所有數據都是相同的)
  2. 查詢然後找到第一個孩子,其排序的值與您指定的值匹配第一個參數。
  3. 然後,查詢將採用(可選)秒並刪除其鍵之前的任何項目。

因此,在你的查詢,如果你想要在接下來的4項1498230632003...後:

ref 
    .orderByChild("published") 
    .startAt(1100, "1498230632003-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7") 
    .once("value", function(snap) { 
    console.log("#2 Results: "+snap.numChildren()); // Results: 2 
    snap.forEach(function(child) { 
     console.log(child.key); // 1498230632003..., 1498230632000... 
    }); 
    }); 

如果你想確定從哪裏開始基於關鍵字查詢結果,你應該使用orderByKey()

ref 
    .orderByKey() 
    .startAt("1498230632003-3M7VnZESptDyGP4iN6BXlNqi6ukG4HgWkX4KvwiWEKs%3D_15cd582aa38%3A50c8a%3A35f03cd7") 
    .once("value", function(snap) { 
    console.log("#2 Results: "+snap.numChildren()); // Results: 1 
    snap.forEach(function(child) { 
    console.log(child.key); // 1498230632003... 
    }); 
}); 

我不完全確定,但它似乎是你想要獲得一個查詢,以訂購一個屬性和過濾器上的密鑰。這在Firebase數據庫查詢模型中是不可行的。爲了您的選項,請參閱http://stackoverflow.com/questions/26700924/query-based-on-multiple-where-clauses-in-firebase

我jsbin來進行測試:https://jsbin.com/xuwaxaq/edit?js,console

從一小段代碼是很難理解的。我建議我的更地道的變體替換它們:

countObj(data.val()) 

是一樣的:

snap.numChildren() 

和:

var lastKey = getLastKey(data); 

是一樣的:

var lastKey; 
snap.forEach(function(child) { lastKey = child.key; }); 
+0

謝謝,我會給這個去,並馬克回答,只要我確定我理解:) – REJH