简体   繁体   English

Orientdb NoSQL有条件地执行查询

[英]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. 我正在使用OrientDB REST API,并试图找到一种方法来检查边缘并创建边缘(如果仅使用一个POST请求则不存在)。 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: 我编写了一个查询来检查OrientDB内置的Tolkien-Arda数据集中的边缘:

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. 查询的这种丑陋性仅计算了从rosaBaggins到adalgrimTook有多少条边,如果返回大于0,则返回“ true”,否则返回false。

However I'm not sure how to go the next step and execute the CREATE EDGE query if true. 但是我不确定如何进行下一步并执行CREATE EDGE查询(如果为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: 如果您希望通过Java API做到这一点,则此代码检查是否存在从rosaBaggins到adalgrimTook的传出边缘:

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 由于没有提到它是用Java编写的,因此我仅向您提供此Edge Upsert的纯SQL实现

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. 我没有使用tolkien-Arda的原始代码,但可以随意填写该代码。

The structure consists of a user and a story written by him. 该结构由用户和他编写的故事组成。 If they aren't linked yet an edge (user_story) is created. 如果尚未链接,则会创建边缘(user_story)。

Using part of @mitchken 's answer, I've figured it out. 使用@mitchken的答案的一部分,我已经弄清楚了。

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. 第一次将此脚本发送到服务器时,会在“ asdfasdf”(我刚刚创建的一个顶点)和“ adalgrimTook”之间创建一个新边,并返回新边的@rid。 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. 还需要注意的另一个重要事项(让我很沮丧地弄清楚了这一点)是,LET语句在Web GUI的CLI或“浏览”选项卡中将不起作用,但可以很好地用作POST脚本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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