Search code examples
orientdb

OrientDB : Single shot Query


I have some doubts related to the queries in orientdb. I have below scenario:

Example :

   Performs    Uses          RunsOn    IsConnected 

User --> Process --> Application --> Server --> Network

Here, User/Process/Application/Server/Network are Vertex Names
Performs/Uses/RunsOn/IsConnected are Edge Names / Relationship Names osType/applicationName are Attribute Names for related Vertex

Now, I want all the related combination result as per the input. If input is like osType of Server and applicationName of Application then i want all the details related to this two inputs like user and process and whatever is related to this applicationName and osType.

It is possible in orientdb to fetch out all this details in a single query ??


Solution

  • If you want single columns

     MATCH
      {as:user} -Performs-> {as:process} -Uses->
      {class:Application, as:app, where:(applicationName = ?)} -RunsOn->
      {class:Server, as:server, where:(osType = ?)} -IsConnected-> {as:network}
     RETURN user.name, process.id, app.name, server.url, server.name, network.name 
    

    if you only need the RIDs of the involved elements:

     MATCH
       {as:user} -Performs-> {as:process} -Uses->
       {class:Application, as:app, where:(applicationName = ?)} -RunsOn-> 
       {class:Server, as:server, where:(osType = ?)} -IsConnected-> {as:network}
     RETURN user, process, app, server, network
    

    If you also want all the details in line:

     SELECT user.* as user_, process.* as process_, app.* as app_, server.* as server_, network.* as network_ FROM (
       MATCH
         {as:user} -Performs-> {as:process} -Uses->
         {class:Application, as:app, where:(applicationName = ?)} -RunsOn->      
         {class:Server, as:server, where:(osType = ?)} -IsConnected-> {as:network}
       RETURN user, process, app, server, network
     )
    

    The "as xxx_" will add a prefix to attributes, this is useful to avoid collisions, eg. if you have user.name and server.name, this way you will have "user_name" and "server_name"

    If you don't need all the patterns, but you only need single records that are part of the result:

     MATCH
       {as:user} -Performs-> {as:process} -Uses->
       {class:Application, as:app, where:(applicationName = ?)} -RunsOn-> 
       {class:Server, as:server, where:(osType = ?)} -IsConnected-> {as:network}
     RETURN $elements
    

    If you have multiple paths connected to the same node, you can use comma separated patterns, joined using aliases, eg.

    MATCH
     {as:user} -Performs-> {as:process} -Uses->
     {class:Application, as:app, where:(applicationName = ?)} -RunsOn-> 
     {class:Server, as:server, where:(osType = ?)} -IsConnected-> {as:network},
     {as:server} -IsMountedOn-> {as:storage}
    RETURN $elements
    

    If one or more of the (terminal) connections is missing, you can define it as optional, eg. if the storage can be missing:

    MATCH
     {as:user} -Performs-> {as:process} -Uses->
     {class:Application, as:app, where:(applicationName = ?)} -RunsOn-> 
     {class:Server, as:server, where:(osType = ?)} -IsConnected-> {as:network},
     {as:server} -IsMountedOn-> {as:storage, optional:true}
    RETURN $elements
    

    This works only on terminal nodes, ie. nodes that have only one connection.

    Full reference here: http://orientdb.com/docs/2.2.x/SQL-Match.html