2017-08-12 21 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