EzDevInfo.com

bulbs

A Python persistence framework for graph databases like Neo4j, OrientDB and Titan. Bulbflow: a Python Framework for the Graph Era

Use neo4j with R

Is there a R library that supports neo4j? I would like to construct a R graph (e.g. igraph) from neo4j or - vice versa - store a R graph in neo4j.

More precisely, I am looking for something similar to bulbflow for Python.


Update

There is a new neo4j driver for R that looks promising: http://nicolewhite.github.io/RNeo4j/. I changed the correct answer.


Source: (StackOverflow)

How do I connect to orientdb graph through rexster with bulbs?

So, I'm using python3.2 and bulbs on mac-osx with rexster and orientdb. Details:

orientdb - standard download from their page

~/workspace/orientdb-community-1.7-rc1

Running the server, ./bin/server.sh

database - orientdb database ~/databases/orientdb/dev-db-01

rexster - standard checkout from github git clone git://github.com/tinkerpop/rexster.wiki.git ~/workspace/

config/rexster.xml:

        ...
        <graph>
        <graph-enabled>true</graph-enabled>
        <graph-name>dev-db-01</graph-name>
        <graph-type>orientgraph</graph-type>
        <graph-location>local:*<path to...>*/databases/orientdb/dev-db-01</graph-location>
        <properties>
            <username>admin</username>
            <password>admin</password>
        </properties>
        <extensions>
            <allows>
                <allow>tp:gremlin</allow>
            </allows>
        </extensions>
    </graph>
    ...

Python code:

from bulbs.rexster import Graph
from bulbs.config import Config
config = Config("http://localhost:8182/dev-db-01/", username="admin", password="admin")
g = Graph(config)

Problem:

Traceback (most recent call last):   File "<stdin>", line 1, in <module>   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rexster/graph.py", li ne 56, in __init__                                                 

    super(Graph, self).__init__(config)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/base/graph.py", line  58, in __init__                                                 

    self.vertices = self.build_proxy(Vertex)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/base/graph.py", line  124, in build_proxy                                             

    return self.factory.build_element_proxy(element_class, index_class)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/factory.py", line 19,  in build_element_proxy                                      

    primary_index = self.get_index(element_class,index_class,index_name)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/factory.py", line 27,  in get_index                                                

    index = index_proxy.get_or_create(index_name)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rexster/index.py", li ne 80, in get_or_create                                            

    resp = self.client.get_or_create_vertex_index(index_name, index_params)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rexster/client.py", l ine 668, in get_or_create_vertex_index                              

    resp = self.gremlin(script, params)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rexster/client.py", l ine 356, in gremlin                                                 

    return self.request.post(gremlin_path, params)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rest.py", line 131, i n post                                                    

    return self.request(POST, path, params)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rest.py", line 186, i n request                                                 

    return self.response_class(http_resp, self.config)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rexster/client.py", l ine 198, in __init__                                                

    self.handle_response(response)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rexster/client.py", l ine 222, in handle_response                                         

    response_handler(http_resp)   File "/opt/local/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/bulbs/rest.py", line 39, in  not_found                                                

    raise LookupError(http_resp) LookupError: ({'date': 'Thu, 20 Feb 2014 07:08:20 GMT', 'status': '404', 'access-control-allow-origin': '*', 'content-lengt h': '0', 'server': 'grizzly/2.2.16'}, b'')

What I think is that the url in the config of the python code is incorrect (I've tried all kinds of variations). But I don't know that; it works if I leave the rexster.xml untouched and just use the standard graph constructor; but then that's a problem, because it's not adding nodes to the orientdb database that I want, dev-db-01, it's putting them in a default database. So to make sure that I connected to the right database, I disabled all but the orientdb database I had created.

How do I make it connect properly?


Source: (StackOverflow)

Advertisements

Is there a equivalent to commit in bulbs framework for neo4j

I am building a data-intensive Python application based on neo4j and for performance reasons I need to create/recover several nodes and relations during each transaction. Is there an equivalent of SQLAlchemy session.commit() statement in bulbs?

Edit:

for those interested, an interface to the Bulbs have been developped that implements that function natively and otherwise functions pretty much just like SQLAlchemy: https://github.com/chefjerome/graphalchemy


Source: (StackOverflow)

Choosing an appropriate way to use Neo4j in Python

I am currently using embedded python binding for neo4j. I do not have any issues currently since my graph is very small (sparse and upto 100 nodes). The algorithm I am developing involves quite a lot of traversals on the graph, more specifically DFS on the graph in general as well as on different subgraphs. In the future I intend to run the algorithm on large graphs (supposedly sparse and with millions of nodes).

Having read different threads related to the performance of python/neo4j bindings here, here, I wonder whether I should already switch to some REST API client for Python (like bulbflow, py2neo, neo4jrestclient) until I am too far to change all code.

Unfortunately, I did not find any comprehensive source of information to compare different approaches.

Could anyone provide some further insight into this issue? Which criteria should I take into account when choosing one of the options?


Source: (StackOverflow)

ORM with Graph-Databases like Neo4j in Python

i wonder wether there is a solution (or a need for) an ORM with Graph-Database (f.e. Neo4j). I'm tracking relationships (A is related to B which is related to A via C etc., thus constructing a large graph) of entities (including additional attributes for those entities) and need to store them in a DB, and i think a graph database would fit this task perfectly.

Now, with sql-like DBs, i use sqlalchemyś ORM to store my objects, especially because of the fact that i can retrieve objects from the db and work with them in a pythonic style (use their methods etc.).

Is there any object-mapping solution for Neo4j or other Graph-DB, so that i can store and retrieve python objects into and from the Graph-DB and work with them easily?

Or would you write some functions or adapters like in the python sqlite documentation (http://docs.python.org/library/sqlite3.html#letting-your-object-adapt-itself) to retrieve and store objects?


Source: (StackOverflow)

The most appropriate way to use Neo4j from Python in 2015

I'm using latest community Neo4j (2.2.0-M03) for storing my graphs. I'm interested in accessing it from Python. According to the official Neo4j documentation, there are several alternatives.

From what I have understood by checking the docs, playing around a bit, and checking this post, py2neo is the only one supporting Neo4j 2 (and labels). However, if I'd like to write and run specific algorithms on Neo4j, I should use Gremlin, through Bulbs, that however does not seem to support Neo4j 2.

Now, I would like to use some custom algorithms not currently in Neo4j, like Spreading Activation. Is writing algorithms directly in Neo4j in Java and running them from Python using cypher commands through py2neo the only alternative? Am I missing something?

Cheers

PS. I wanted to post links to all the software I cited but unfortunately I need at least 10 reputation to post more than 2 links...


Source: (StackOverflow)

Proper way to update Edges in Bulbs (neo4j or titan)

I'm experimenting with Bulbs to interface with a graph database. ( Production will use Titan, locally Neo4j seems best for experimenting ).

I can't wrap my head around this concept...

Bulbs shows how to create new Vertices...

>>> james = g.vertices.create(name="James")
>>> julie = g.vertices.create(name="Julie")
>>> g.edges.create(james, "knows", julie)

Digging into the docs, I can replace that with a "get or create" as well :

>>> james = g.vertices.get_or_create('name',"James",{'name':'james')

What I can't figure out, is how to get an existing Edge. My attempts so far have ended up with recreating dozens of "james knows julie" relationships, instead of accessing the existing one to update.

Can someone point me in the right direction?


Source: (StackOverflow)

Selective indexing in bulbflow without using Models

I'm using bulbflow (python) with Neo4j and I'm trying to add an index only on a subset of my keys (for now, simply keys named 'name' for optional index-based lookup).

I don't love the bulbflow Models (too restrictive) and I couldn't figure out how to do selective indexing without changing code since the 'autoindex' is a global setting -- I don't see how to configure it based on the key.

Has anyone done something like this?

-Andrew


Source: (StackOverflow)

error messages using Bulbs/python and Neo4j 2.0

Using Neo4j 2.0 and Python 2.7.6 - I've tried executing several scripts based the Bulbs package, but keep getting the following errors:

Traceback (most recent call last):
  File "D:/neo4jdb/testingbulbs2.7", line 8, in <module>
    james = g.vertices.create(name="James")
  File "C:\Python27\lib\site-packages\bulbs\element.py", line 565, in create
    resp = self.client.create_vertex(data, keys=_keys)
  File "C:\Python27\lib\site-packages\bulbs\neo4jserver\client.py", line 424, in create_vertex
    return self.create_indexed_vertex(data, index_name, keys=keys)
  File "C:\Python27\lib\site-packages\bulbs\neo4jserver\client.py", line 1027, in create_indexed_vertex
    return self.gremlin(script,params)
  File "C:\Python27\lib\site-packages\bulbs\neo4jserver\client.py", line 384, in gremlin
    return self.request.post(path, params)
  File "C:\Python27\lib\site-packages\bulbs\rest.py", line 128, in post
    return self.request(POST, path, params)
  File "C:\Python27\lib\site-packages\bulbs\rest.py", line 183, in request
    return self.response_class(http_resp, self.config)
  File "C:\Python27\lib\site-packages\bulbs\neo4jserver\client.py", line 217, in __init__
    self.handle_response(response)
  File "C:\Python27\lib\site-packages\bulbs\neo4jserver\client.py", line 249, in handle_response
    response_handler(response)
  File "C:\Python27\lib\site-packages\bulbs\rest.py", line 39, in not_found
    raise LookupError(http_resp)
LookupError: ({'status': '404', 'access-control-allow-origin': '*', 'content-type': 'application/json; charset=UTF-8', 'content-length': '838', 'server': 'Jetty(9.0.z-SNAPSHOT)'}, '{\r\n  "message" : "No such ServerPlugin: \\"GremlinPlugin\\"",\r\n  "exception" : "PluginLookupException",\r\n  "fullname" : "org.neo4j.server.plugins.PluginLookupException",\r\n  "stacktrace" : [ "org.neo4j.server.plugins.PluginManager.extension(PluginManager.java:124)", "org.neo4j.server.plugins.PluginManager.invoke(PluginManager.java:165)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:312)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:134)", "java.lang.reflect.Method.invoke(Unknown Source)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:132)", "org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112)", "java.lang.Thread.run(Unknown Source)" ]\r\n}')

I noticed there are additional EOL characters in some of the error messages. Could that be the problem?


Source: (StackOverflow)

passing a variable with colon in function python

I am using this api.. whose function call looks like:

g.vertices.index.lookup(identifier="value")

Now note that idenitifier is a variable which I have not defined but is resoluted by api and value is a string.

Something similar happens in pymongo api: http://api.mongodb.org/python/current/tutorial.html

db = client.test_database

is equal to

db = client["test_database"]

test_database in first case, even though user hasnt defined that variable.. but is understood by mongo that in my datastore, do i have a database called test_database or not..

Now, the issue I have is this: I have a colon in my datastore..

Which is to say it is like:

g.vertices.index.lookup(bad:identifier="value")

See.. the colon in the query..

And this api doesnt have that mongo type dictionary implementation..

I know, I should resolve this as in why I am getting this colon.. but this is what I am stuck at right now..

And the issue is because of that colon, I get

g.vertices.index.lookup(bad:identifier="value")
                           ^
SyntaxError: invalid syntax

How do i resolve this


Source: (StackOverflow)

Bulbflow: difference between neo4jserver Graph and neo4jserver Neo4jclient

I am now trying to learn how to connect to Neo4j server and run Cypher queries on it using Bulbflow from Python. And the thing I do not understand is the difference between two possibilities to connect to the neo4j server:

1) Graph

from bulbs.neo4jserver import Graph
g = Graph()

2) Neo4jClient

from bulbs.neo4jserver import Neo4jClient
client = Neo4jClient()

Could anyone please explain the conceptual difference here? And which way is it better to choose if I then want to execute (quite a lot of) Cypher queries against the server and ultimately in parallel?

PS: I do not have enough reputation to create a tag "bulbflow" for this question :)


Source: (StackOverflow)

No such ServerPlugin: GremlinPlugin

I want put some data to Neo4j database using python script. I think bulbflow can be easy way how to do that.

I have this little script from their homepage and docs.

#!/usr/bin/python
from bulbs.neo4jserver import Graph
g = Graph()
james = g.vertices.create(name="James")

But when I run it, I get this error:

Traceback (most recent call last):
  File "./bulb.py", line 4, in <module>
    james = g.vertices.create(name="James")
  File "/usr/lib/python2.7/site-packages/bulbs/element.py", line 565, in create
    resp = self.client.create_vertex(data, keys=_keys)
  File "/usr/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 424, in create_vertex
    return self.create_indexed_vertex(data, index_name, keys=keys)
  File "/usr/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 1054, in create_indexed_vertex
    return self.gremlin(script,params)
  File "/usr/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 384, in gremlin
    return self.request.post(path, params)
  File "/usr/lib/python2.7/site-packages/bulbs/rest.py", line 131, in post
    return self.request(POST, path, params)
  File "/usr/lib/python2.7/site-packages/bulbs/rest.py", line 186, in request
    return self.response_class(http_resp, self.config)
  File "/usr/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 217, in __init__
    self.handle_response(response)
  File "/usr/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 249, in handle_response
    response_handler(response)
  File "/usr/lib/python2.7/site-packages/bulbs/rest.py", line 39, in not_found
    raise LookupError(http_resp)
LookupError: ({'status': '404', 'access-control-allow-origin': '*', 'content-type': 'application/json; charset=UTF-8', 'content-length': '833', 'server': 'Jetty(9.0.5.v20130815)'}, '{\n  "message" : "No such ServerPlugin: \\"GremlinPlugin\\"",\n  "exception" : "PluginLookupException",\n  "fullname" : "org.neo4j.server.plugins.PluginLookupException",\n  "stacktrace" : [ "org.neo4j.server.plugins.PluginManager.extension(PluginManager.java:124)", "org.neo4j.server.plugins.PluginManager.invoke(PluginManager.java:165)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:312)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:134)", "java.lang.reflect.Method.invoke(Unknown Source)", "org.neo4j.server.rest.transactional.TransactionalRequestDispatcher.dispatch(TransactionalRequestDispatcher.java:139)", "org.neo4j.server.rest.security.SecurityFilter.doFilter(SecurityFilter.java:112)", "java.lang.Thread.run(Unknown Source)" ]\n}')

bulbflow and Neo4j is properly installed according to http://bulbflow.com/download/. Neo4j is running with default configuration and I am able to open http://localhost:7474/.

Can you please help me with this issue?

Thank you, FrostyX


Source: (StackOverflow)

Rexster OrientDB configuration

i'm trying to setup Rexster (version 2.5) to work with OrientDB (1.7 rc2). The problem is that i don't know what should i put in the <graph-type> field in the graph configuration. Most recent Rexster documentation (https://github.com/tinkerpop/rexster/wiki/Specific-Graph-Configurations) states that OrientDB support was removed from the package, and therefore one has to copy orientdb-client and orientdb-enterprise jars from OrientDB distribution.

So that's what i did. Then i've setup the <graph> section as follows:

<graph>                                                                                                        
  <graph-enabled>true</graph-enabled>                                                                        
  <graph-name>test</graph-name>                                                                            
  <graph-type>com.tinkerpop.blueprints.impls.orient.OrientGraphRexsterConfiguration</graph-type>                             
  <graph-location>local:orientdb/databases/test</graph-location>                        
  <extensions>                                                                                               
    <allows>                                                                                               
      <allow>tp:gremlin</allow>                                                                          
    </allows>
  </extensions>                                                                                              
</graph>

I get java.lang.ClassNotFoundException: com.tinkerpop.blueprints.impls.orient.OrientGraphRexsterConfiguration upon Rexster startup.

I've also tried setting up Rexster 2.1, which works just fine when using orientgraph for <graph-type> (as per https://code.google.com/p/orient/wiki/Rexster). This approach fails for 2.5. I feel that i must be missing something obvious. Can someone please point to the solution?

Thanks!


Source: (StackOverflow)

Not able to use bulbs to program Titan GraphDB/Rexster

I have Titan (with embedded cassandra running on my system).

cd titan-cassandra-0.3.1
bin/titan.sh config/titan-server-rexster.xml config/titan-server-cassandra.properties

I have rexster server running

cd rexster-console-2.3.0
bin/rexster-console.sh

I am able to create a graph from the rexter shell using Gremlin queries.

 g = rexster.getGraph("graph")
 v1 = g.addVertex([name:"s1"])
 v2 = g.addVertex([name:"s2"])
 e1 = g.addEdge(v1, v2, "likes")

I have installed bulbs on my system as follows.

sudo apt-get install python2.7-dev
sudo apt-get install libyaml-dev

sudo pip install  https://github.com/espeed/bulbs/tarball/master

If I try the following from ipython on my machine

In [1]: from bulbs.rexster import Graph

In [2]: g = Graph()

I get the following error.

---------------------------------------------------------------------------
LookupError                               Traceback (most recent call last)
/home/karthik/Projects/ryu_extras/<ipython-input-2-eb1ac0314e67> in <module>()
----> 1 g = Graph()

/usr/local/lib/python2.7/dist-packages/bulbs/rexster/graph.pyc in __init__(self, config)
     54 
     55     def __init__(self, config=None):
---> 56         super(Graph, self).__init__(config)
     57 
     58         # Rexster supports Gremlin


/usr/local/lib/python2.7/dist-packages/bulbs/base/graph.pyc in __init__(self, config)
     56         self.factory = Factory(self.client)
     57 
---> 58         self.vertices = self.build_proxy(Vertex)
     59         self.edges = self.build_proxy(Edge)
     60 

/usr/local/lib/python2.7/dist-packages/bulbs/base/graph.pyc in build_proxy(self, element_class, index_class)
    122         if not index_class:
    123             index_class = self.default_index
--> 124         return self.factory.build_element_proxy(element_class, index_class)
    125 
    126     def load_graphml(self, uri):

/usr/local/lib/python2.7/dist-packages/bulbs/factory.pyc in build_element_proxy(self, element_class, index_class, index_name)
     17         proxy_class = element_class.get_proxy_class()
     18         element_proxy = proxy_class(element_class, self.client)
---> 19         primary_index = self.get_index(element_class,index_class,index_name)
     20         element_proxy.index = primary_index
     21         return element_proxy

/usr/local/lib/python2.7/dist-packages/bulbs/factory.pyc in get_index(self, element_class, index_class, index_name)
     25             index_name = element_class.get_index_name(self.client.config)
     26         index_proxy = self.build_index_proxy(element_class, index_class)
---> 27         index = index_proxy.get_or_create(index_name)
     28         return index
     29 

/usr/local/lib/python2.7/dist-packages/bulbs/rexster/index.pyc in get_or_create(self, index_name, index_params)
     78 
     79         """ 
---> 80         resp = self.client.get_or_create_vertex_index(index_name, index_params)
     81         index = self.index_class(self.client,resp.results)
     82         self.client.registry.add_index(index_name, index)

/usr/local/lib/python2.7/dist-packages/bulbs/rexster/client.pyc in get_or_create_vertex_index(self, index_name, index_params)
    666         script = self.scripts.get('get_or_create_vertex_index')
    667         params = dict(index_name=index_name, index_params=index_params)
--> 668         resp = self.gremlin(script, params)
    669         #assert "MANUAL" in resp.content['results'][0]

    670         result = {'name': index_name, 'type': 'manual', 'class': 'vertex'}

/usr/local/lib/python2.7/dist-packages/bulbs/rexster/client.pyc in gremlin(self, script, params, load)
    354         if self.config.server_scripts is True:
    355             params["load"] = load or [self.scripts.default_namespace]
--> 356         return self.request.post(gremlin_path, params)
    357 
    358 

/usr/local/lib/python2.7/dist-packages/bulbs/rest.pyc in post(self, path, params)
    129 
    130         """
--> 131         return self.request(POST, path, params)
    132 
    133     def delete(self, path, params=None):

/usr/local/lib/python2.7/dist-packages/bulbs/rest.pyc in request(self, method, path, params)
    184         http_resp = self.http.request(uri, method, body, headers)
    185 
--> 186         return self.response_class(http_resp, self.config)
    187 
    188 

/usr/local/lib/python2.7/dist-packages/bulbs/rexster/client.pyc in __init__(self, response, config)
    196     def __init__(self, response, config):
    197         self.config = config
--> 198         self.handle_response(response)
    199         self.headers = self.get_headers(response)
    200         self.content = self.get_content(response)

/usr/local/lib/python2.7/dist-packages/bulbs/rexster/client.pyc in handle_response(self, http_resp)
    220         headers, content = http_resp
    221         response_handler = RESPONSE_HANDLERS.get(headers.status)
--> 222         response_handler(http_resp)
    223 
    224     def get_headers(self,response):

/usr/local/lib/python2.7/dist-packages/bulbs/rest.pyc in not_found(http_resp)
     37 
     38 def not_found(http_resp):
---> 39     raise LookupError(http_resp)
     40     #return None

     41 

LookupError: ({'status': '404', 'transfer-encoding': 'chunked', 'server': 'grizzly/2.2.16', 'date': 'Sat, 10 May 2014 06:22:49 GMT', 'access-control-allow-origin': '*', 'content-type': 'application/json'}, '{"message":"Graph [emptygraph] could not be found"}')

What does these mean?


Source: (StackOverflow)

Gremlin / Bulbflow: How to select nodes based on their edges and related vertice's properties

Sorry for the long post, but I want to avoid any misunderstanding about what I'm looking for :)

I am currently discovering graph databases, and experimenting a bit with bulbflow/neo4j. Thus, I am trying to use gremlin for most of my requests, but I do not know if the request I want is even feasible or not. I may even be wrong about trying to use a graph db for such a use case, so don't mind telling me whether you think I'm on the right path or not.

First, let me provide a bit of context:

I work on an early-stage open-source project, which is a compiler for a DSL language generating C code. We are currently planning to re-write the whole thing in python for many many reasons (the language, re-designing, opening to a community and such...). The compiler includes what I'll call a cache of the compiled interfaces and templates. The interfaces describe the templates, and each template is associated to a configuration (a list of typed values associated to variables described by the interfaces).

The aim of the request I'm wishing to build is to select a single template implementation depending on an input configuration (actually used in the generation mechanism of the compiler). In the end, I want to be able to request directly through gremlin (if possible at all) a single element I'm looking for in order to provide unicity for the elements that can be found within this "cache". Currently, I manually match this configuration in the python code, but I want to know if it is feasible to do it directly within gremlin.

-

So let's define a sample graph for my use-case: We have three types of vertices:

  1. Def (Definition), contains a String property called "signature", which is actually the signature of the template defined by this node.
  2. Impl (Implementation), containing two properties which are pathes to the original source and pre-compiled files.
  3. Var (variable), containing a String property which is the signature of the variable.

Then, a few kind of edges:

  • Def -> impl_by -> Impl (multiple implementations can exist for a definition, does not contain any property)
  • Impl -> select_by -> Var (Implementations may be selected through a constraint over a configuration variable's value, each edge of this type contains actually three properties: type, value, and constraint - a comparison operator -)

The selected_by edge (or relationship, following bulflow's vocabulary) describes a selection constraint, and thus has the following properties:

  • val (value associated to the variable for the origin implementation)
  • op (comparison operator telling which kind of comparison to make for the constraint to be valid or not)

This translates as a graph such as (I'll omit the types from the selected_by edges in this graph):

              -- select_by { value="John", op="="}  ---------
              |                                              \
    (1)--Impl--- select_by { value=12, op=">"}      ------    \
    |                                                     \    \
    |                                                      \    |- Var("name")
    |         |- select_by { value="Peter", op="="} -----------/
Def (2)--Impl--                                              \/
    |         |- select_by { value=15, op="<"}      ----     /\
    |                                                   \   /  \
    |                                                    |-/----|--- Var("ver")
    (3)--Impl--- select_by { value="Kat", op="!="}  ------/    /
            |                                                 /
            |--- select_by { value=9, op=">"}       ---------/

What I want to do is to select one (or more) Impl depending on their relationship with the Vars. Let's say I have a configuration as follows:

Config 1:

variable="name", value="Peter"
variable="ver", value=16

This would select Impl(3) Since Peter != Kat AND 16 > 9, but not Impl(1) since Peter != John nor Impl(2) since 16 !< 15.

I was blocked on multiple levels, so I was starting to wonder if this was even feasible:

  • I could not find how to give such arguments (the configuration) to a gremlin script
  • I could not find how to select the Impl based on conditions over the outgoing edges.

I hope this wasn't too confusing.

Cheers, and thanks !

EDIT:

I managed to make part of my request work, by using repeatedly backtracking and filters. The request (X being the starting vertex, VALUE the value I want to match, and NAME the name of the variable to be matched) looks like this:

Basis of the request:

g.v(X).out('impl').as('implem')

Repeat this part for each couple VALUE/NAME:

.out('select_by').filter{it.value=='VAL‌​UE'}
.inV('select_by').filter{it.name=='NAME'}
.back('implem')

The only thing currently missing is that I do not know how to use the select_by edge's 'op' property to determine how to build the filter to use. For instance, thre are cases where I want to match exactly the configuration (and thus, as in this request, I ignore the 'op' property), but there are cases where I want to take the 'op' property into account, and use the associated comparator in the filters.

Is there any way to do that ? (Or should I post another question?)


Source: (StackOverflow)