简体   繁体   English

Gremlin 查询中的条件执行

[英]Conditional execution in a Gremlin query

Is there a way to conditionally execute part of a gremlin query, based on data external to the query, not based on the graph.有没有一种方法可以根据查询外部的数据,而不是基于图形,有条件地执行部分 gremlin 查询。

I'm using Go, the Gremlingo driver and AWS Neptune.我使用的是 Go、Gremlingo 驱动程序和 AWS Neptune。 I've been able to do this from my code, but it is not that pretty.我已经能够从我的代码中做到这一点,但它并不那么漂亮。 Here's how I did it.我是这样做的。

func (n NeptuneGremlinGraph) Put(assetID string, version string, records []les.DeltaEditRecord) error {
    g := gremlin.Traversal_().WithRemote(n.connection)
    anonT := gremlin.T__
    for _, r := range records {
        promise := n.addParent(g.V().HasLabel("Entity").
            Has("asset_id", assetID).
            Has("version", version).
            Has("entity_id", r.EntityID).
            Fold().
            Coalesce(anonT.Unfold(),
                anonT.AddV("Entity").
                    Property("asset_id", assetID).
                    Property("version", version).
                    Property("entity_id", r.EntityID)).
            Store("e").
            V().HasLabel("Component").
            Has("asset_id", assetID).
            Has("version", version).
            Has("entity_id", r.EntityID).
            Has("component_id", r.ComponentID).
            Fold().
            Coalesce(anonT.Unfold().
                Property("value", r.Value),
                anonT.AddV("Component").
                    Property("asset_id", assetID).
                    Property("version", version).
                    Property("entity_id", r.EntityID).
                    Property("component_id", r.ComponentID).
                    Property("value", r.Value)).
            AddE("ATTACHED_TO").To(anonT.Cap("e").Unfold()), anonT, "e", assetID, version, r).Iterate()
        err := <-promise
        if err != nil {
            return err
        }
    }

    return nil
}

func (n NeptuneGremlinGraph) addParent(graphTraversal *gremlin.GraphTraversal, anonT gremlin.AnonymousTraversal, e, assetID, version string, record les.DeltaEditRecord) *gremlin.GraphTraversal {
    if !n.hasParent(record) {
        return graphTraversal
    }

    parent := n.getParent(record)
    return graphTraversal.V().
        HasLabel("Entity").
        Has("asset_id", assetID).
        Has("version", version).
        Has("entity_id", parent).
        Fold().
        Coalesce(anonT.Unfold(),
            anonT.AddV("Entity").
                Property("asset_id", assetID).
                Property("version", version).
                Property("entity_id", parent)).
        AddE("CHILD_OF").From(anonT.Cap(e).Unfold())
}

It would be really slick if I could add a new method to gremlin.GraphTraversal, but I don't think you can add methods to a struct in another package. I suppose that I could also do it with two completely independent queries, in a transaction.如果我可以向 gremlin.GraphTraversal 添加一个新方法,那将非常巧妙,但我不认为你可以向另一个 package 中的结构添加方法。我想我也可以用两个完全独立的查询来做到这一点,在一个交易。

Just wondering if there is something I missed and that there is a way to do this within the query.只是想知道是否有什么我错过了,并且有一种方法可以在查询中执行此操作。

There are a couple of different approaches here.这里有几种不同的方法。 First, you can build up a query dynamically in code.首先,您可以在代码中动态构建查询。 As in your example above, if your second method accepted a graph traversal object as a parameter, that could be appended with additional steps before then being returned as a graph traversal object. Simple pseudocode here:如上面的示例所示,如果您的第二种方法接受图形遍历 object 作为参数,则可以附加额外的步骤,然后作为图形遍历 object 返回。这里是简单的伪代码:

func AddFilter(query,parameter) {
    return query.has('key',parameter);
}

GraphTraversal new = g.V().has('somekey','somevalue');

queryResult = AddFilter(new,'value').next();

Graph traversals are not sent to the server until you append a Terminal Step at the very end.直到您在最后执行 append 终端步骤后,图遍历才会发送到服务器。

A more involved way of doing this would be to create your own DSL in a way to "extend" the query language to simplify reused query components.一种更复杂的方法是创建您自己的 DSL,以“扩展”查询语言以简化重用的查询组件。 The docs cover this in detail here: https://tinkerpop.apache.org/docs/current/reference/#gremlin-go-dsl文档在这里详细介绍了这一点: https://tinkerpop.apache.org/docs/current/reference/#gremlin-go-dsl

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

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