简体   繁体   中英

Orientdb NoSQL conditionally execute a query

I'm using the OrientDB REST API and am trying to find a way to check for an edge and create it if it does not exist using only one POST request. Multiple queries and commands are fine, just want to minimize the overhead created by back and forth with the server.

I have written a query to check for the edge in OrientDB's built in Tolkien-Arda dataset:

SELECT IF(COUNT(*) FROM 
(SELECT FROM Begets
WHERE OUT IN (SELECT FROM Creature WHERE uniquename='rosaBaggins') 
AND IN IN (SELECT FROM Creature WHERE uniquename='adalgrimTook')) > 0, "True", "False")

This ugly monstrosity of a query just counts how many edges are going from rosaBaggins to adalgrimTook and returns "true" if it returns more than 0 and false otherwise.

However I'm not sure how to go the next step and execute the CREATE EDGE query if true. Help appreciated with this or with writing my insane query more efficiently, I get the feeling that I've done it the hard way.

If you want you can do that through Java API, this code check if an outgoing edge from rosaBaggins to adalgrimTook exist:

String DB = "<db name>";
String path = "remote:localhost/" + DB;
OServerAdmin serverAdmin;

try
{
    serverAdmin = new OServerAdmin(path).connect("<username>", "<password>");
    if(serverAdmin.existsDatabase())
    {
        OrientGraphFactory factory = new OrientGraphFactory(path);
        OrientGraph g = factory.getTx();

        Iterable<Vertex> result = g.command(new OCommandSQL("SELECT FROM #18:0 WHERE out().uniquename contains 'adalgrimTook'")).execute();
        List<Vertex> list = new ArrayList<Vertex>();
        CollectionUtils.addAll(list, result.iterator());

        if(list.size() == 0)
        {
            System.out.println("Edge doesn't exist, I'm creating it ...");
            g.command(new OCommandSQL("CREATE EDGE connection FROM (SELECT FROM Creature WHERE uniquename = 'rosaBaggins') TO (SELECT FROM Creature WHERE uniquename = 'adalgrimTook')")).execute();
        }
        else
        {
            System.out.println("Edge already exist");
        }

        serverAdmin.close();
    }
}
catch(Exception e)
{
    e.printStackTrace();
}

Hope it helps

Regards

Since it was not mentioned to be in Java I'll just provide you the pure SQL implementation of this edge Upsert

let $1 = select from user where _id = 'x5mxEBwhMfiLSQHaK';
let $2 = select expand(both('user_story')) from story where _id = '5ab4ddea1908792c6aa06a93';
let $3 = select intersect($1, $2);
if($3.size() > 0) {
  return 'already inserted';
}
create edge user_story from (select from user where _id = 'x5mxEBwhMfiLSQHaK') to (select from story where _id = '5ab4ddea1908792c6aa06a93')
return 'just inserted';

I did not use the original code from the tolkien-Arda, but feel free to fill that code in.

The structure consists of a user and a story written by him. If they aren't linked yet an edge (user_story) is created.

Using part of @mitchken 's answer, I've figured it out.

LET $1 = SELECT expand(bothE('Begets')) from Creature where uniquename='asdfasdf';\
LET $2 = SELECT expand(bothE('Begets')) FROM Creature WHERE uniquename='adalgrimTook';\
LET $3 = SELECT INTERSECT($1, $2);\
LET $4 = CREATE EDGE Begets FROM (SELECT FROM Creature WHERE uniquename='asdfasdf') TO (SELECT FROM Creature WHERE uniquename='adalgrimTook');\
SELECT IF($3.INTERSECT.size() > 0, 'Already exists', $4)

Sending this script to the server the first time creates a new edge between 'asdfasdf' (a vertex I just created) and 'adalgrimTook', and returns the @rid of the new edge. The second time I send the script to the server, it returns 'Already exists'.

Also important to note (took me a lot of frustration to figure this out) is that the LET statements will not work in the CLI or Browse tab on the web GUI, but work just fine as a POST script.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM