 So my name is Darren Wood, I work for Objectivity and primarily, obviously, I work on a product called Lymphenograph, which is a graph database. And I'm going to run through some introductory stuff to both graph databases and the product into the graph. And then we also have a little bit of a preview because we're about to be able to release 3.0 of Lymphenograph, so we've got some previews of the features that are coming down the line in that as well. And so I'll talk through some of those things at the back of this. So it's interesting because I do give this presentation of, you know, it's sort of different types of conferences. Not all of them specialize in Mohs equal. So, you know, this slide's really about sort of trying to explain what Mohs equal is. And I guess I don't need to do that as much in an audience like this because everybody who's coming to this conference obviously is very much interested in alternative database solutions, and they're looking for their data specialist. So, you know, obviously Mohs equal is all about, you know, specializing in some kind of, you know, database set of requirements. That's essentially what it is. So, you know, in the early days of Mohs equal, when people were essentially building their own Mohs equal database, and when I say early days, it's been going on forever. You know, essentially what they were doing was saying, well, you know, off the board, databases don't really provide what we need from a database, right? Because they have rules and constraints or, you know, the way that they represent themselves to the user doesn't exactly meet their requirements. So that could be for a number of different reasons. It could be it's not storing the data in a way that makes it, you know, performant for me to get that data back. So, you know, I'm not able to read the data fast enough. You know, there might be, you know, some constraints around the way that transactions are managed in that type of database that makes, you know, locking, coming to play and cause applications to weigh into each other and, you know, certain types of applications don't want to do that. So, those equal databases essentially break down, you know, some of the main goals of building a database and specialize in certain types of data or certain types of behavior in the database. And graph databases are no different. So it's really strange because, you know, for so long, relational databases have been so pervasive, whereas, you know, we specialize in every other aspect of our life. So this is essentially just specializing in data. And that's kind of what NoSQL is. So for a graph database, of course, you know, we specialize in the storage of graph data. So, you know, what does that exactly mean? So this whole, you know, rise of NoSQL databases and, you know, many of them have been around for a long time, in fact, and have just sort of become popular or, you know, people have started to see the benefits of them. But it's sort of giving rise to these types of polyglot type, you know, NoSQL architectures where you're mixing multiple databases together, you're taking the strengths of each one. You're storing the type of data that best suits that database into, you know, into a particular flavor of NoSQL database. So, you know, you might have something at the front end, so this might be a, you know, a web-scale type application that is serving your users directly, and you need a certain type of databases for that because you need to be able to, you know, show them their profile information, you need to be able to scale reads and writes to that information really well. So you might be storing that in a certain way. But then you've got things in the back end, you know, you might be using a Doop or MapReduce or something, or MapReduce on top of a Doop, you know, to do sort of large-scale crunching of numbers or crunching of user data to try and figure out something about your user that might, you know, your market spending in some way or something like that. And then you're taking the output of that and storing it in another type of data store that is good for querying that data, right? So you're kind of taking, you know, rings of data that you're getting from your users or from your user's behavior or the things they're doing on the web, and you're putting them into, you know, a massive, scalable, you know, big data store. You're crunching that information down, and the stuff that's coming out of the other end, you know, there's all different kinds of data that can be stored in different kinds of ways and get really performing in terms of, you know, query performance that make it easy to get that information back. So of course, Relation Databases is still really good for some aspects of that, and, you know, you've got the other style of NoSQL Databases document, and of course, I'm going to focus mostly on the Graph Database, which is when you can, you know, you can see the problem or see the type of data you're looking to store as a graph that becomes useful to do traversal style queries in that data. Graph Database is a really good choice. So, you know, becoming a specialist, a specialist type of database, what does it really mean? I mean, what are you doing? Are you just sort of putting some API on top of a relational database and then saying, well, can't you see? You know, we presented this data as some other format and some other way to you. So, you know, now we're a Graph Database. We're a specialist type of database. Well, that's actually not what it means. I mean, becoming a true specialist in the database area means going all the way to the way that the data is physically stored and optimizing it around that use case. Okay? So, as I just explained, you know, queries in the Graph Database often involve traversal relationships in the data. That's pretty straightforward. So, you know, this is a really simplified slide, really high-level slide that sort of shows the way a piece of data about some relationships between people and this is phone call requirements might be stored in a relational database versus how it would be stored in a Graph Database like in the graph. And here you've got, essentially, the list of phone calls for everybody in the system in a big table in the relational database. And of course, what that means is, you know, as the number of people in the database grows and the number of calls they're making grows, the size of this table is going to continue to grow. That's going to be a giant big table. And for me to find the phone calls that Bob has made, I have to go through this giant big table and I have to filter on, you know, this column here and say, you know, who made this column. Of course, I can use indexes to speed it up and I can partition this table and I can do all kinds of fancy stuff. But at the end of the day, if it's really, if that's what you want to do in your query, go into the bold node and look at the phone calls that just Bob has made and see who they've been made to, you're much better storing it that way. And that's how a Graph Database stores its data. Okay, so it basically stores the physical entities in the database, its vertices, and it stores the relationships between that vertex and other things in the database, you know, in a very compact form of way. So we can get that back and we can traverse those relationships super fast. So the traversal of these relationships is what a Graph Database is all about. So that's the main goal. I think this is kind of a really fundamental slide to introducing Graph Databases. So, you know, you'll see a bunch of the Graph Database vendors doing similar slides like this. This is true. I mean, we took a bunch of relational databases and like I said, as the number of nodes in the graph increases and the number of connections between the nodes in the graph increase, relational databases do have this asymptotic sort of fall-down in the way that you can traverse that data. Okay, so you can implement a Graph Database and a Relational Database, but here's a couple of, you know, different sort of open source and commercial RDVMSs that we read in books of edge files against. And of course, it's very easy for a Graph Database to win because, you know, this test is essentially going into a node and saying, now, traverse out all the things that surround this node. And of course, that's what we store at that node. You don't have to go through everybody else's relationships and filter them out or, you know, use any kind of, any kind of, you know, reading these giant tables and filtering through them. We'd have to do any of that. So we have an advantage and that describes what our advantage is for this particular type of query. That's the specialist part. So, you know, when you start talking about node SQL databases, everybody wants to know, well, you know, how do you scale your writes, how do you scale your reads, you know, how does your distribution work, how do you, you know, scale out horizontally and make these faster. And there's a number of different aspects to that. Okay, so obviously there is, you know, there is partitioning. So you can basically set up your database so it's partitioned across, you know, some series of machines or posts in the cloud or whatever. And then essentially what you do is you get the ability to write to multiple places. You've got more machines, more servers, more CPUs, it's actually processing those queries of those writes. And that's true. So that's one way. But then you start running into, you know, understanding where your consistency requirements are. I mean, a bunch of you have probably been to dozens of presentations on consistency and the trade-offs you've known SQL around. And I think that some of the best-known SQL databases give you options and choices around that with the API order. So what they say is, you know, if I have a node in my graph and I need to update that node, for example, I want to add two edges to it, an edge between this node and two other things in the graph, you know, that node in the middle is a point of locking, it's a point of contention. So do I, you know, can I do that in a way that locks other things from changing it so I get a consistent, you know, move from one state to another? Well, can I feed that information into the graph somehow and let the database sort out how that's done? And it will be eventually consistent. So over time, you know, that graph will build up in the background. And usually the graph has ways to allow you to do that. So that's what these slides describe here. So again, a very simple example. You've got three nodes in your graph, two edges you want to put in. The guy in the middle, if I have two applications, one at this edge and one at that edge, do I want the two applications to wait or do I want them to be able to add the edge into the database? So, you know, quite common in, you know, no SQL type deployments and certainly in the prospects that we see. You've got applications that are just streaming data in from all these different sources. You've got a phone call data coming in here. You've got intelligence data coming in over here. Not all these applications want to just sit there and lock on every individual node that they want to update. So we allow you to break that down into graphs so you can do something called pipelining so you can push edges in. And the graph builds in the background. We take care of that. Of course, when you do a reading, you're reading, you know, a consistent state of the database, but these edges are being added in the background for you. So they're being, the graph's being built in an eventually consistent way. So, you know, that's one way that we scale writes. Specifically, scaling edge writes. And this is probably way to do that. This is part of the architecture that's, you know, this is built on. We have, you know, this ability to deploy agents into the database to actually do this processing in the background. So we have a database server as such that can run on multiple hosts and it's horizontally scalable. And your clients are just forcing data in and building the graph up in the background. You don't have to wait. However, we do have a fully acid mode, right? So again, choice. Choice is really important. So if you want to take an application and say, no, I need to lock, you know, add this edge because another application might not see that edge and I want to have, you know, this atomic update to the database, you can go back into that mode. You do that in the API that will give you the choice. Very important. So of course, trade-offs, as I just explained, you know, you see a very high perceived ingest rate. So as your data's arriving, you can just add nodes, add edges, you know, connect edges up in the graph. So your clients are not blocked doing that. They go straight into the database. However, you know, the trade-off is consistency, right? So as you're doing a navigation, you may not necessarily see the edge that was added, you know, by an application a couple of milliseconds ago. All right, but the important thing here is choice. And of course, the result is this, you know, a very nicely sort of horizontal scalable ability to push data into the database. This is some graph made out of some of our performance testing. I'm pretty modest hardware in the office in a raid, I'm sorry, a rack or a raid of machines and racks. So with the consistency, is that, you know, a nothing thing or is that kind of per application? No, yeah, so it's actually per transaction. So yeah, so when you start the transaction, you can decide that that transaction is going to start blocking stuff, right? And then, you know, you can start a different type of transaction that says, you know what, this goes in, blocks of the other transactions are taken into it. So they can help you come down after grabbing data out of the, you know, garbage place or something like that. That can be eventually consistent. Exactly, yeah, that's right. Or maybe something coming in from, you know, their brain action. Yeah, and that actual use case is a really good one because quite often those devices, and we've seen this before, they operate in burst, right? Yeah, yeah. So they say, we do an experiment and then it's just a ton of data coming down. We just want to get them in, you know, just want to push them in. We don't want to be blocking things like that. So just push it in. And this will then process, reprocess the background. And then, you know, so you've got this sort of very, you know, jumpy sort of ingest range, right? Where you want to push a bunch of stuff in, and then it's nothing, and then push a bunch of stuff in, and this works really well for that. So scaling reads and query, okay, so, you know, in a lot of cases, you know, especially in sort of the key value space and whatnot, you know, in other, in relation databases as well, it's relatively simple to replicate and scale the reads, okay? So you can make replicas of the data. They might not be consistent replicas, but you can make replicas of the data. You can push out, read replicas, you know, update them as, you know, as necessary in the background. And that's pretty easy for a, you know, for a key value store or a relational database, you know, partitioning tables, partitioning key space and key value stores in document databases as well, partitioning key space for the documents. Relatively easy to do. With a graph, it's a bit different, because graphs look like this, okay? So, you know, graph data is just all connected to each other. So it's a bit of a mess, and of course, the result of a query might look like this, right? So you're actually getting pieces of a result from various partitions in the database, all right? Which means that it's not as easy to sort of just say, well, I'm just going to slice this data up, and I'm going to send all the queries that go for that partition of the data down this server. And it's replicas perhaps, and you might have a partition and replicas of that partition. It's much easier to do that. In a graph, it's quite a bit more difficult. So there's a bunch of solutions to this. So some of you may have read about cradle, and cradle sort of turns the whole problem upside down. So what it says, it says, look, in the graph, what we're going to do is we're going to store the budget nodes, you know, sort of partition across the dataset, and you're going to have all the nodes laid out in the partition. Every time we want to do part of a reversal from one node to another, all we'll do is we'll wrap up the context of that navigation, and we'll send that to the home of the node where it's going. So we'll follow, essentially we follow these relationships, like I've shown here, and we sort of follow them using messaging between the processes on each host. That's a normal solution. It really simplifies processing queries in graph data. It boils it down to essentially, as a processor, and all I have to do is wind the handle and all the messages coming into my host comes in, it says I'm going here, it does some evaluation, looks at the context, looks at the rules of the traversal, and then it says, where am I going next? And so, if I'm going here and I still wrap up a message, you know, and I send it to myself, you know, it goes back in the queue and the process is just winding this queue. If I'm going over there, I send a message to that guy. It simplifies, you know, graph traversal. So, it's a novel idea. But one of the problems with Parable is that it does exactly that. I mean, it simplifies it, so all this context wrapping, sending messages either to each other or to itself is quite expensive. I mean, you have to format the data and you have to have ways to do that and there's only so much you can put in there and, you know, there's rules around that and so it's restrictive and it can be quite expensive, especially when it's on a low price. So, if you had cash here that had all these nodes in here and you're constantly wrapping messages up and sending it to itself, you're sort of wrapping and unwrapping for no reason. But it's simple, right? It's simple, it's the most part good. And the second one here is kind of like a distributed caching model. So, what you do is you kind of take, you know, this same sort of architecture, but what you do is you bring pieces of the graph that are commonly used with each other into cash on, you know, the various possibilities. So, what you end up with is like sort of pieces of the graph stored in memory that, you know, sometimes is open. So, you might store some of this over here in memory and so you come up with this kind of, you know, distributed caching. And infinite graph was doing this. So, this is kind of the approach the infinite graph was using. But we started to head down a path which I think is even better. So, with infinite graph now, and some of this is being introduced into the new release in the third and the bit that will be coming out soon, we're making decisions about that. So, we can still send pieces of a query to the host where the majority of that data lives. But we can also process some hosts of the query in memory in our cache. Because actually when we do a traversal in memory in our cache, it's actually two C++ objects sitting in a piece of heap space and the connection is actually a pointer. So, hopping across that is so much faster than trying to wrap a message up or sending a thing. So, we also have really good statistics and really good data about what's in our cache and things about what's going on. So, this is the direction we're heading in the infinite graph. Making very smart choices about when we need to distribute a piece of the traversal and send it off to a location that's more apt at processing that piece of the navigation versus doing it in memory in our cache. And of course, this is fully flexible around how much cache you've allocated because you've got more cache and you've allocated plenty of cache on the host and we can bring it in and bring it in. But there's a limit to that so that's when you want a system that's kind of a hybrid you can do by it. So, this whole schema thing especially in a NoSQL concept conference is going to be a tough one to debate because, you know I'd say at least 90% of NoSQL databases kind of fade to the concept of a schema-less database. So, the whole schema versus schema is made I'm sure it's happening out in the whole way a thousand times an hour and it's very religion-based, it's almost database-religion. So, I don't really have time for a full debate about here except just to show you that we have a couple of use cases and again a couple of things that are coming out in IG3 that I think are very compelling reasons to have a schema in your graph database. So, I'll sort of go through those. Having said that, we're also planning to have document-style data nodes as well. So, essentially a schema-less data node. But, again, we're very big on choice. I mean, one of our real sort of mandates in IG3 is to offer choice. So, you can use schema for the parts of your data where that makes sense or use a schema-less sort of document node where you'd rather have the flexibility. So, it's just trade-offs. The flexibility is great until it gets out of control and you have no idea what its shape of your objects are. So, everybody knows the two sides of the argument. We're sort of hoping to give some choice so you can flip-flop between them and you can mix them actually in your data source. So, here's one and I know this side's kind of bland for the one color scheme here. But, these are essentially think about this like classes in your graph, right? And this is an example from a real system. I had to sort of take some things out. But anyway, there's about 200 classes in this real system that this represents and that's how I was trying to scale it down to some, you know, set of classes that make sense, right? But still have some good examples for traversals and validations. So, this is obviously healthcare data, right? So, it's actually reasonably simple to represent healthcare data as a graph. And, you know, I can tell you a lot of the healthcare data people in healthcare organizations themselves are looking at graph databases to store healthcare data because it makes sense, right? And there's a lot of types of queries you want to do in healthcare data that work really well on the graph. They work really well as traversals. So, you know, this is pretty straightforward after a run through this. You go patient, they have a visit with a physician, right? And this visit might be a location or something. There's lots of different things that can go into this graph. Sometimes, there's outcomes on those visits. So, they have a set of, you know, something that happens there, like they've diagnosed you with something or other. And in this case, we have an allergy as an outcome, right? Now, this could be a giant class, I reckon. And this could be a very, very rich series of outcomes, right? Outcome is the base class. That's the type of thing that a visit can have connected to it. But you've got, you know, all kinds of outcomes, right? You can just keep adding them. And they, you know, healthcare organizations like that because we're always finding new things that are wrong with people. And, you know, they like to go to the extended set. So, this is a big class, I reckon, with hundreds of classes in it. But I've shown the allergy one for one reason. It's because I want to make an example of it. So, let's say you're at the patient and you're about to prescribe them a drug. And that drug, you know, it's, the doctor doesn't really know a lot about the patient necessarily. They might have come from somewhere else. They might have been treated in another facility or whatever. So, they've got a bunch of, you know, pre-existing prescriptions. But they've also got allergies to things. So, right, how does the doctor know, you know, what drugs are okay with you people? Apparently, this is actually really dangerous. There's actually kills a lot of people every year. So, this is a really, real problem for, um, so what I'm trying to do is, given a prescription, I know that the prescription will be associated with the drug. But the prescription doesn't matter because I haven't prescribed it yet. But that will be stored later when I do actually prescribe it. But I want to start at the patient and I want to find any route from here through an allergy, right, as an outcome here. So, you know, I can identify this allergy as being an important part of this traversal to an ingredient that they are allergic to. And the drug is connected to the ingredient, right, because drugs are made up of ingredients and they're allergic to some pieces of the drug. So, like I said, this graph can be gigantic. I mean, there's all kinds of things hanging off, you know, all these data notes here. There's a really big graph of data. So, one thing you might like to be able to do is kind of filter this, take a view of the data that only includes the relationships that you know are important for that traversal, right. So, it's actually going to be able to do this, right. So, to take everything out and sort of break a clear path for the information you're actually looking for. And then a traversal becomes very easy to write. You basically say, okay, we're given this view of the data now. I'm looking for any way this patient is connected to this drug, right. Because any way through this avenue that they connected to this drug will be important because it will be through analogy, right. And so, graph views that we're introducing, again, infinigraphary, allow you, and this happens at a very high level, to filter out all the types of the data that don't make any sense for that particular navigation. And this is really, really powerful. And it's even more powerful than I've described here because we can also infer things. So, even if this edge type was reused somewhere else and it led to some other different type, we can say, well, you know what, on the other side of that edge is this type that doesn't go anywhere in this view. And so, we can optimize that out as well. So, we can infer that going somewhere ahead of time won't go anywhere to our result. And so, we kind of compile the graph view before the navigation is run. And it's kind of hard to explain and get in your head, but this is an extremely powerful way to do traversals in the graph database. And so, again, this is another very interesting way to speed up, to become a specialist in a certain type of data and speed up navigational queries. And graph view is, I think, really powerful. And again, this is just an alternative example to say, well, you know, we're investigating positions, so we want to iterate across positions and we want to see how maybe they're over-describing. We want to see, you know, is there some kind of spike where somebody's just giving out this drive all the time for potentially no reason, right? So, we can again do another view that cuts out all the other stuff in the position, you know, just the position's relationship to the prescriptions and, of course, ultimately to the drive. And we can plug the positions in to an iterator and we can take the drive that we're targeting out and see how they can look at the counts for how many times it's described. Very quick again. And then, there's another side to this as well, and that is configured placement. And when I talk about placement I talk about physically where data is stored in the database. So, again at the lowest level of how the database operates, being able to control physically how the data is stored. So, you know, I talked about that, you know, the graphs have been messed, right? It's all over the place. Well, again, with InventGraph3.io, we're giving you the ability to kind of give some hints and advice on how you should organize that graph to make it faster for sort of localized traversals. So, for example, you know, I've given another healthcare example here, right? So, you've got data that's usually always related to the patient, right? So, the patient's visits, right, will be known to the graph potentially and there will be relationships that point out to other parts of the graph and things like that. You might want to do traversals. But if you've got a lot of queries that just sort of iterate around, you know, patient's visits and things like that, it would be really nice if you could sort of hint to the database that these visits should really live with their patient, right? And say, give you a way to sort of put them nearby. And this could end up on the same physical data pages that we read from the database, so therefore you get less page faults and you you're reading a much fewer number of fewer pages to actually get the information back you want. And of course you could do the same thing with facilities. So, you know, facilities have doctors to maybe co-locate into doctors with facilities and things like that. And we can do this in a declarative way. You don't have to actually, you know, put all of this sort of functionality to your code or into your data even. You don't have to, you know, model that specifically. We can actually create a model that's outside of the application and it will automatically do this kind of thing for you. So, this is again a really, really powerful way because although this, I'm showing you kind of like you know, what we're doing that the effect is, again, faster reads but certain types of traversal so I mean, the effect of this is dramatic. So, we'll do our five minutes. Five minutes to whiz through the rest of these slides. Okay, so you know, why InfiniGraph? Okay, so we've got InfiniGraph has been around for a couple of years but the company objectivity has been building distributed databases for you know, some number of years since 93, so a very long time. We understand data. We've been doing it for a long time. We've got a very customer stable customer base, sorry. It's a complete dbms. You know, we have transactions. I talked about having various transaction modes and having choices in that but it's a complete database management system. It's not something that's writing into files and then hoping the best thing will happen. I mean, it's a proper database. So, and it's a specialist. I mean I've run through a few examples here. It's not a graph layer on an rdbms. It's a specialist database for storing graph data. So, I talked about some of these layers here. It's a fully distributed data model. You know, we have the concept of you know, where data is stored physically you can configure outside of you know, the application of course. The application just sees, hey, I want to put something in the database. We obviously have a distributed model which you can configure. You can add storage locations. We can even define zones. So, if you've got pieces of data that you want to be stored in the same rack of machines, then you can, you know, co-locate them in zones. Things like that. So, what's the vertex? Sorry? So, is there another standard for guns for the graph databases like vertex and stuff like that? More or less, yeah. I mean, some people call it nodes and you know, edges, vertexes and edges for the same sort of thing. Is it standard across the graph databases? The naming of them? I mean, the concepts are pretty much the same. The names, I'm not too sure of various APIs, you know, we'll call them different things. We've got the Neo guy in the back of the room. We call it node, right? No, node in Neo, vertex in the back of the page. The concept is the same, you know, joining nodes with edges. What's the 9% of the users using graph databases called nodes? 99. Yeah, probably. Yeah, we're rebels now. We go against the graph. How distributed do you see zones? You actually define data centers around the world? Right. So, you define what's in a zone. So, you collect a group of hosts into a zone, you define that. So, if it's in a rack or it's in a physical location within the data center, that's up to you. You know, to a local machine. So, you can say, here this data really belongs, you know, and again, with different graph, you can really store the data wherever you like, you know, it can be right up to the desktop, and you really want it to architect it that way. And you can have pieces of the graph stored up there. You can define that as design as well. Yeah, we get a lot of requests, but we don't, usually iPads are a client, but not directly, no. So, you know, I think I've been through this, and I'm running out of time. It's a super simple API. So, of course, it's specialist, so, you know, the API looks like you're hooking up a graph, you're creating instances of vertexes, of nodes in the graph, and you're hooking them up. You can see this makes perfect sense. You know, I talked about how, you know, it's tied to the schema, so you juggle classes and that to types of the database, so it's very, you know, native for programmers to work with in the graph. This is at the end of the course, so, you know, setting up a meeting, Alice at Edge, end of the meeting makes sense. It just reads as it is. And of course, that's the result of the code show. That's the whole slide there. So, I talked a little through traversals, you know, how do you query a graph database, and I was talking about, well, it's like this traversal, which is kind of like this trip that starts at some point, you know, which is your start nodes, your origin here on the slide. And it goes out in the graph looking for whatever it's looking for, right? So, that could be, you know, another node. So, in the drug example I gave, you're starting at a patient and you're looking for a drug, right? And you're looking for it through these various types of relationships. That's one type of traversal. You might, it could be a fuzzy traversal as well. You might not know what you're looking for. So, you might define predicates, like, I mean, predicate query language, we have a query language which is based on predicates, so you can say, well, I'm looking for this kind of thing and here are some of the fields from that. It might be, you know, something Smith, you know, or something like that. So, you can define that kind of thing as well. And so, you know, there's lots of different types of navigational queries. Of course, you can define a strategy, breadth first, depth first, the views I talked about in some detail there. You can also define qualifiers in code and compile them into the query as well so you can say, you know, I need to specify this very tightly. You know, I want to write a piece of code that qualifies the fact that this traversal is going well, right? So, along the way I can say, you know what, I've got to hear I'm looking back in the path how I got here and this doesn't qualify I want to get out. I want to bail out this traversal. You can even go down to that level. So, you can write very, very detailed queries into the graph data. Of course, you know, result handle is so we have a delegate-based sort of result handle where things results back to you. And in fact, this is something that people lie. We have a sort of an event-based, you know, when you perform a navigation in an infinite graph, you don't say go and then wait for it to figure out what all the results are and then get them back as a result set. They actually fire them back to you as an event. So, if you get the first one and then your application is doing something on it and says, yeah, you know, that's what I need and it can kill off the navigation. Or you can wait, you know, and so intelligent people like this, right? They've got massive data sets and all your phone calls you make and they go off and they want to find something. And then the first thing they get back, they can go off and investigate and they might be waiting for other things to come back. They go off and investigate. So, it's really nice to have pieces of the result coming back as they happen as they're found. We've got a visualizer tool. So, you know, this is really nice customizable sort of UI. So, we can hook this up to any graph with your data and your data model in it. You can customize the graph lines. And what you can do is you can build some of those traversals I was talking about and you can load them up into this and execute them and look at the results. So, you can, it's like a test. I mean, it's like the regular, with an RMS, you've got like a little thing where you can test a SQL query. This is testing navigation. But it shows you the results as a graph. So, it shows you the start node and all the things that navigated to and how it got there. It's pretty nice little... So, I can zip through the practical applications a little bit at a time. We use part-finding a lot to say how is this person here we don't really know related to you know, crime games and things that we already know about. It's an obvious use case for the graph. We have some really good samples of this running out on our, our booth out in the exhibit area. So, you can go and look at some of these running. You can see how fast it does traversals and navigations into learned graphs. Our rhythms on graphs, obviously, you know, degree centrality is really important for people to see who has the, who is highest connected so who has the most things connected to them and obviously also things like closeness and betweenness centrality who is the middle of the graph, right? They're often the king hints, right? So, they're not having much communication but everything goes through there. So, it makes them suspicious in crime networks and things like that. Of course, social networks, you know, to some extent are a graph problem, right? Because friends are connections and things like that. So, you've definitely got that in there. Business intelligence, you know, looking at ways that your processes are connected in a big graph and then sort of doing cause analysis and things like that. You can start at something happening and, you know, go and look at all the, the outflow from that as a graph. Very really, you know, some really interesting use cases there. You know, local crime, you know, intelligence of course is one of the biggest ones. Security, recognizing attack and threat patterns, you know, quite often that can be done with a graph and visualize the network data as a graph and you can look at security from that perspective as well. Advertising is a really good one, you know, sort of seeing what people's browsing behavior is and connecting them into products and things like that. So, when you want to place an ad, you just come into person mode, start looking around what things are recently looked at or like or whatever. It's a nice graph problem as well. And there's a bunch more. I talk about healthcare. Obviously, you know, health sciences and genealogy and things like that are also a big use case. And, I guess I'm holding everybody back from lunch. So, I won't do any further. So, there's any questions? You can come up and talk to me or I'll stay out with people a little bit as well or I'll be around for a little while. Thank you.