I have an ordered list of firebase locations. I'm using a property ut (update time) as their priority. I want to make the list such that it's easy to get the latest updated documents.
So I set the priority to be negative ut.
var query = fb.child('view/documents').limit(20)
query.on('child_added', function(child) {
console.log(child.val())
console.log(child.getPriority())
})
I expect something like this to return the latest 20 documents, but it doesn't, it returns the oldest 20. In the forge I see the listing the way I expect it, the latest documents are on top, but the query is sending me the bottom 20. It seems contrary to my expectations for the query to send me the bottom 20 instead of the top 20.
What really confuses me is that the child_added returns the expected order, latest (smallest priority) first. But again it's the oldest in the list.
Am I doing something wrong or is this a bug in firebase.
Thanks.
I understand your confusion, but that's really how it's supposed to work: limit(20) returns the 20 greatest-priority children, starting with the 20th-greatest-priority child and ending with the absolute-greatest-priority child (and then updating whenever a new child is added whose priority is great enough to make the list).
You can see the example at https://www.firebase.com/docs/queries.html, where the priority is the Unix timestamp of when the message was sent, and messageListRef.limit(100) is used to get the 100 most recent messages (i.e., the 100 greatest-priority messages).
I think what you are looking for is : .startAt()
before the limit(), that will return the data in correct order, without the keyword you will always get the last specified number of children.
Here is the reference : https://www.firebase.com/docs/javascript/query/limit.html
Related
Am I not using select() properly in my code? When I re-select("pair") for some reason, what it contained originally has been updated after performing some step. Shouldn't what was labeled using as() preserve what was contained?
g.V()
.hasLabel("Project")
.hasId("parentId","childId").as("pair")
.select("pair")
.hasId("parentId").as("parent")
.select("pair") // no longer what it was originally set to
I think this is expected. You (presumably) find two vertices with hasId("parentId","childId") and so the first select("pair") would of course show each vertex. But, then you filter again, hasId("parentId") and kill the traverser that contains the vertex with the id of "childId". It gets filtered away and therefore never triggers the second/last select("pair") step and would only therefore return the one vertex that has the id of "parentId".
I'm using the new gcloud-java API (https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore) for working with the Cloud Datastore. My specific question is on using GQL for pagination with cursors. I was able to page through the results one page at a time in the forward direction using cursors, but not having any luck with paging backwards.
Example Scenario:
Let's say I've 20 entities in a Kind with IDs 1 through 20. I have a page size of 5. Once I'm on the 3rd page (IDs 11 through 15), if I need to go one page back; i.e. retrieve IDs 6 through 10, what would be the correct GQL/sample code? Again, I prefer not to use offset with a number, but would like to use Cursors.
From what I can tell (actually tested), it looks like one needs to keep track of Start/End cursors for each page as they navigate in the forward direction, then use the saved cursors when there is a need to go back. I just want to make sure if this is the correct/only way or there is a simpler way to accomplish this.
Thanks in advance for your help.
If you add to your original query a sort by key (appended to the end of your "order by" clause), you should be able to reverse each property's sort order and use the latest cursor from your original query to get results in reverse.
Suppose you've iterated through some of the values from your forward query's QueryResults. You can call QueryResults's cursorAfter() method, which will return a cursor pointing right after the last result you saw from your original query. Now you can issue a new query (with the opposite sort order on each property, including the key property) using that cursor as the start cursor. You'll probably want to skip the first result, since it will be the last result you saw from the original query.
When my app starts up, I want it to grab the latest changes from Evernote - that is, the changes since it last updated. As part of that process, I want to see what's been moved to the trash recently. Looking at a Note type, it has a created, updated and deleted timestamp.
I went to the NoteStore.findNotesMetadata function, which takes a NoteFilter as an argument. NoteFilter has a NoteSortOrder argument, which is the way in which the notes returned are sorted. NoteSortOrder has the options:
CREATED
UPDATED
RELEVANCE
UPDATE_SEQUENCE_NUMBER
TITLE
There isn't an option to sort notes by date deleted. The date created and modified remain the same as they did before, and so without grabbing the metadata of every note there's ever been, there doesn't seem to be a way for me to see what's been deleted recently.
Any thoughts as to how I could go about sorting by the deleted timestamp?
You will need to get all the metatdata and then sort it. You can use the NotesMetadataResultSpec to limit the amount of data you get. In this case you can set the includeDeleted flag to TRUE, which will only the deleted timestamp of all notes. You can then do another metadata fetch to get the rest of the metadata.
This is not directly related to sort by date deleted. However, I found it to be useful, so I am posting it here.
If you want to control the sort order regardless of when the notes were created or last updates, just put 0., 1., 2., and so on, in front of each note title. That will keep the notes in the order you assign.
This is not a big deal, but I wanted to throw it out there - if you had 100 items with incremental priorities, you would have a list like this:
item#1: { .priority: 1 }
...
item#100: { .priority: 100 }
The first item is #1 with priority 1, and the last item is #100 with priority 100. Now if you LIMIT() the list to 3 items, like this:
firebaseRef.limit(3).once(...)
Rather than being returned items 1-3, you would be returned items 97-100. Do most people expect that? It's the opposite of how limits generally work in other environments. In SQL for example, you start at the beginning of the set and stop when you hit the limit.
Now this isn't a technical limitation or anything (I believe), because we can actually get records 1-3 pretty easily by using STARTAT() on the first item:
firebaseRef.startAt(1).limit(3).once(...)
In fact, when LIMIT() is used without STARTAT() or ENDAT() it actually behaves like you specified ENDAT() with the last item. For example these produce the same results:
firebaseRef.limit(3).once(...)
firebaseRef.endAt(100).limit(3).once(...)
Doesn't it seem like the default behavior should be to mimic STARTAT() from the first position, rather than ENDAT() from the last position, if only LIMIT() is specified?
You are absolutely right in concluding that the default behavior works as if endAt() was used (and thus the latest items will be returned). This is because in the most common use cases you'd want to display the latest data, not the oldest; eg: chat history or notifications.
How do I check the .priority values are in my "Forge"?
According to docs, smaller .priority value comes before larger .priority value. If I use seconds since epoch for priority, and I want the latest children to show up on top, should I set .priority to be 1/seconds?
Children with a number as their priority come next. They are sorted numerically by priority (small to large) and then lexicographically by name (a to z).
From experimentation, I've determined that if I set .priority to java.util.Date#getTime, oldest children show up on top in my Forge, but latest children show up on top in my Javascript on() when ranking using prevChildName. Why is this?
You can see .priority in a json by "Export JSON" from the Forge.
use
snapshot.getPriority();
more at
https://www.firebase.com/docs/javascript/firebase/setwithpriority.html
It's not available from Forge but you can see it from the JSON format:
https://YOURAPP.firebaseio.com/.json?print=pretty&format=export
There's no way in Forge right now to see the actual priority values, but the children will be sorted correctly.
If what you want is to sort items in reverse-chronological-order, I'd suggest simply setting the priority to a normal timestamp (or using push -- it orders them automatically). You can then simply render them backwards to achieve the reverse order you want. For example, rather than appending new messages to the bottom of a list in your app, you could insert them before the first element.
snapshot.exportVal()
Exports the entire contents of the DataSnapshot as a Javascript
object. This is similar to val(), except priority information is
included (if available), making it suitable for backing up your data.
The export format is a Javascript object with ".priority" entries
added to any object with a priority. In the case of primitive values
(a string, number, or boolean) with a priority, the value is wrapped
in an object with ".value" and ".priority" properties. In the case of
primitive values without a priority, a primitive value is returned.
Source: https://www.firebase.com/docs/web/api/datasnapshot/exportval.html