<div dir="ltr">Just found that file in the repo before I saw your message and I think I understand now - thanks!<div><br></div><div>So, if you're looking at a node below the root (an ArchivalObject) that has >200 children, you would hit the ".../tree/waypoint" endpoint however many times and include "parent_node" in the GET params with the ArchivalObject URI, right?</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jul 23, 2019 at 11:57 AM Majewski, Steven Dennis (sdm7g) <<a href="mailto:sdm7g@virginia.edu">sdm7g@virginia.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="overflow-wrap: break-word;"><div><br></div><div><blockquote type="cite"><div dir="ltr"><div><div><div>So the next question is how do you make the subsequent calls to retrieve the next 200, etc.?</div></div></div></div></blockquote></div><div><div dir="ltr"><div><div><div><br></div></div></div></div></div><div><br></div>You call /repositories/$repo/resources/$id/tree/waypoint?offset=$N 23 times. <div>( You already got the first batch in .precomputed_waypoints in the call to /ress/root ) </div><div><br></div><div><br></div><div>I found the documentation note in the source I was looking for: </div><div><a href="https://github.com/archivesspace/archivesspace/blob/master/backend/app/model/large_tree.rb" target="_blank">https://github.com/archivesspace/archivesspace/blob/master/backend/app/model/large_tree.rb</a></div><div><br></div><div><br></div><div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># What's the big idea?</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># ArchivesSpace has some big trees in it, and sometimes they look a lot like big</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># sticks. Back in the dark ages, we used JSTree for our trees, which in general</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># is perfectly cromulent. We recognized the risk of having some very large</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># collections, so dutifully configured JSTree to lazily load subtrees as the</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># user expanded them (avoiding having to load the full tree into memory right</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># away).</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># However, time makes fools of us all. The JSTree approach works fine if your</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># tree is fairly well balanced, but that's not what things look like in the real</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># world. Some trees have a single root node and tens of thousands of records</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># directly underneath it. Lazy loading at the subtree level doesn't save you</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># here: as soon as you expand that (single) node, you're toast.</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># This "large tree" business is a way around all of this. It's effectively a</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># hybrid of trees and pagination, except we call the pages "waypoints" for</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># reasons known only to me. So here's the big idea:</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># * You want to show a tree. You ask the API to give you the root node.</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># * The root node tells you whether or not it has children, how many children,</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># and how many waypoints that works out to.</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># * Each waypoint is a fixed-size page of nodes. If the waypoint size is set</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># to 200, a node with 1,000 children would have 5 waypoints underneath it.</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># * So, to display the records underneath the root node, you fetch the root</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># node, then fetch the first waypoint to get the first N nodes. If you need</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># to show more nodes (i.e. if the user has scrolled down), you fetch the</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># second waypoint, and so on.</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># * The records underneath the root might have their own children, and they'll</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># have their own waypoints that you can fetch in the same way. It's nodes,</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># waypoints and turtles the whole way down.</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># All of this interacts with the largetree.js code in the staff and public</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># interfaces. You open a resource record, and largetree.js fetches the root</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># node and inserts placeholders for each waypoint underneath it. As the user</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># scrolls towards a placeholder, the code starts building tracks ahead of the</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># train, fetching that waypoint and rendering the records it contains. When a</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># user expands a node to view its children, that process repeats again (the node</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># is fetched, waypoint placeholders inserted, etc.).</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures">#</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># The public interface runs the same code as the staff interface, but with a</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># small twist: it fetches its nodes and waypoints from Solr, rather than from</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># the live API. We hit the API endpoints at indexing time and store them as</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># Solr documents, effectively precomputing all of the bits of data we need when</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo"><span style="font-variant-ligatures:no-common-ligatures"># displaying trees.</span></div><div style="margin:0px;font-stretch:normal;font-size:16px;line-height:normal;font-family:Menlo;min-height:19px"><span style="font-variant-ligatures:no-common-ligatures"></span><br></div><br></div><div><br></div><div><br><div><div><div><br><blockquote type="cite"><div>On Jul 23, 2019, at 11:08 AM, Trevor Thornton <<a href="mailto:trthorn2@ncsu.edu" target="_blank">trthorn2@ncsu.edu</a>> wrote:</div><br class="gmail-m_7888520866059867121Apple-interchange-newline"><div><div dir="ltr">Thanks, Steve. That makes sense, and I tested with a resource with >1000 top level children and I see that only 200 of them are included, which corresponds to the value for "waypoint_size" in the response:<div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><font face="courier new, monospace">{ <br></font><font face="courier new, monospace"> "child_count":4780,<br></font><font face="courier new, monospace"> "waypoints":24,<br></font><font face="courier new, monospace"> "waypoint_size":200<br></font><font face="courier new, monospace">...</font></blockquote><div><div><br></div><div>So the next question is how do you make the subsequent calls to retrieve the next 200, etc.?</div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Jul 23, 2019 at 10:52 AM Majewski, Steven Dennis (sdm7g) <<a href="mailto:sdm7g@virginia.edu" target="_blank">sdm7g@virginia.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>I believe the rationale of the waypoints was that initially, it was expected that resource children/ archival objects would fall into a more balanced tree structure, but it turned out that there were many flat hierarchies with hundreds of top level children, and getting all of the children at once was not working very efficiently. So with they waypoint calls, you may only be getting some of the children, but the display can start populating the tree display while making additional calls for the rest. <div><br></div><div>I may have some postman examples and internal notes around somewhere: I’ll see what I can dig out. </div><div><br></div><div>— Steve. </div><div><br><div><br><blockquote type="cite"><div>On Jul 23, 2019, at 9:05 AM, Trevor Thornton <<a href="mailto:trthorn2@ncsu.edu" target="_blank">trthorn2@ncsu.edu</a>> wrote:</div><br class="gmail-m_7888520866059867121gmail-m_1019186690443663652Apple-interchange-newline"><div><div dir="ltr">Hi everybody-<div><br></div><div>I'm building a service using these API endpoints (or I think I am):</div><div><a href="http://archivesspace.github.io/archivesspace/api/#fetch-tree-information-for-the-top-level-resource-record" target="_blank">[:GET] /repositories/:repo_id/resources/:id/tree/root</a></div><div><a href="http://archivesspace.github.io/archivesspace/api/#fetch-tree-information-for-an-archival-object-record-within-a-tree" target="_blank">[:GET] /repositories/:repo_id/resources/:id/tree/node</a></div><div><br></div><div>These incorporate the concept of "waypoints", which I admit that I'm not familiar with in this context, and it isn't explained very well in the documentation. This is what I have to work with (these are elements included in the API response):</div><div><ul><li>child_count – the number of immediate children</li><li>waypoints – the number of “waypoints” those children are grouped into</li><li>waypoint_size – the number of children in each waypoint</li><li>precomputed_waypoints – a collection of arrays (keyed on child URI) in the same format as returned by the ’/waypoint’ endpoint. Since a fetch for a given node is almost always followed by a fetch of the first waypoint, using the information in this structure can save a backend call.<br></li></ul></div><div>Can anyone explain what exactly waypoints are and how they are different from children? In the examples I've seen, the "precomputed_waypoints" element in the response looks like a convoluted way (an array value of the lone element in an object, which is itself the value of the lone element in another object) to provide the children nodes of the given node (or root). What's the difference?</div><div><br></div><div>Thanks,</div><div>Trevor<br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail-m_7888520866059867121gmail-m_1019186690443663652gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><font size="2" style="background-color:rgb(255,255,255)" color="#666666">Trevor Thornton</font><div><font size="2" style="background-color:rgb(255,255,255)" color="#666666">Applications Developer, Digital Library Initiatives</font></div><div><font size="2" style="background-color:rgb(255,255,255)" color="#666666">North Carolina State University Libraries</font></div></div></div></div></div></div></div></div></div>
_______________________________________________<br>Archivesspace_Users_Group mailing list<br><a href="mailto:Archivesspace_Users_Group@lyralists.lyrasis.org" target="_blank">Archivesspace_Users_Group@lyralists.lyrasis.org</a><br><a href="http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group" target="_blank">http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group</a><br></div></blockquote></div><br></div></div>_______________________________________________<br>
Archivesspace_Users_Group mailing list<br>
<a href="mailto:Archivesspace_Users_Group@lyralists.lyrasis.org" target="_blank">Archivesspace_Users_Group@lyralists.lyrasis.org</a><br>
<a href="http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group" rel="noreferrer" target="_blank">http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail-m_7888520866059867121gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><font size="2" style="background-color:rgb(255,255,255)" color="#666666">Trevor Thornton</font><div><font size="2" style="background-color:rgb(255,255,255)" color="#666666">Applications Developer, Digital Library Initiatives</font></div><div><font size="2" style="background-color:rgb(255,255,255)" color="#666666">North Carolina State University Libraries</font></div></div></div></div></div></div></div>
_______________________________________________<br>Archivesspace_Users_Group mailing list<br><a href="mailto:Archivesspace_Users_Group@lyralists.lyrasis.org" target="_blank">Archivesspace_Users_Group@lyralists.lyrasis.org</a><br><a href="http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group" target="_blank">http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group</a><br></div></blockquote></div><br></div></div></div></div>_______________________________________________<br>
Archivesspace_Users_Group mailing list<br>
<a href="mailto:Archivesspace_Users_Group@lyralists.lyrasis.org" target="_blank">Archivesspace_Users_Group@lyralists.lyrasis.org</a><br>
<a href="http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group" rel="noreferrer" target="_blank">http://lyralists.lyrasis.org/mailman/listinfo/archivesspace_users_group</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><font size="2" style="background-color:rgb(255,255,255)" color="#666666">Trevor Thornton</font><div><font size="2" style="background-color:rgb(255,255,255)" color="#666666">Applications Developer, Digital Library Initiatives</font></div><div><font size="2" style="background-color:rgb(255,255,255)" color="#666666">North Carolina State University Libraries</font></div></div></div></div></div></div></div>