[Neo4j] Neo4j newbie, REST traversing, rest JS debug, springs, neo4j.py and other questions.

Tobias Ivarsson tobias.ivarsson at neotechnology.com
Sun Jul 4 00:42:03 CEST 2010


Hi Sergey,

There are a lot of questions here, I'll take a stab at a few of them. I'll
do it inline for my own sanity's sake, so that I can keep track of what I'm
answering.

On Sat, Jul 3, 2010 at 8:42 PM, Sergey Nikitin <nikitinsm at gmail.com> wrote:

> Hi, Community!
>
> First of all a want to say thanks, everybody for reading my post,
> there will be a lot of questions. I'm Russian web-developer (sorry for
> my English, please correct my mistakes) and half of year I'm looking
> forwards to NoSQL databases, the reason was that one of my project is
> using semantics data, and relational DB doesn't meet the requirements.
> I will write my actions in timeline order, and there will be q.
>
> 1. I read a lot of documentations about neo4j, and found that it could
> be implemented with my loveliest present lang - python
>
> 2. First of all I tried to use neo4j.py (throug JPypi), but I faced
> problem with building, after some time found that I had not properly
> installed JDK on my Ubuntu 9.1, reinstalling solved build problems,
> but the library still doesn't want to work, and I can't figure out
> what's wrong, everything is built but when I'm trying to run:
>
> logger = logging.getLogger('neo')
> logger.setLevel(logging.DEBUG)
> logger.addHandler(logging.StreamHandler())
>
> graphdb = neo4j.GraphDatabase("/path/to/staroge", log=logger)
>
> "/path/to/staroge" is writable, but Jpype backend fails, and I have no Idea
> :'(
>
>
> raises exception:
>
> classpath is:
> ['/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes/geronimo-jta_1.1_spec.jar',
>
> '/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes/neo4j-kernel.jar',
>
> '/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes/lucene-core.jar',
>
> '/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes/neo4j-index.jar',
>
> '/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes/junit.jar',
>
> '/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes/neo4j-remote-graphdb.jar',
>
> '/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes/neo4j-commons.jar']
> ext_dirs is:
> ['/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/classes']
> Trying JCC backend.
> Trying JPype backend.
> /usr/local/lib/python2.6/dist-packages/jpype/_pykeywords.py:18:
> DeprecationWarning: the sets module is deprecated
>   import sets
> Importing native backends failed.
> Traceback (most recent call last):
>   File
> "/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/_backend/__init__.py",
> line 51, in initialize
>     embedded, remote = implementation.initialize(classpath, params)
>   File
> "/usr/local/lib/python2.6/dist-packages/Neo4j.py-0.1_SNAPSHOT-py2.6.egg/neo4j/_backend/reflection.py",
> line 44, in initialize
>     jvm = jpype.getDefaultJVMPath()
>   File "/usr/local/lib/python2.6/dist-packages/jpype/_core.py", line
> 96, in getDefaultJVMPath
>     return _linux.getDefaultJVMPath()
>   File "/usr/local/lib/python2.6/dist-packages/jpype/_linux.py", line
> 36, in getDefaultJVMPath
>     jvm = _getJVMFromJavaHome()
>   File "/usr/local/lib/python2.6/dist-packages/jpype/_linux.py", line
> 55, in _getJVMFromJavaHome
>     if os.path.exists(java_home+"/bin/javac") :
> TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
> Trying pure Python backend.
>

Great that you are using a logger, this makes it possible for me to see the
problem in the stack trace you have provided.

JPype raises an error of being unable add None to a str on a line where it's
adding java_home to "bin/javac", this means that java_home is None. I've
seen this on linux systems before, JPype needs the JAVA_HOME environment
variable to be set in order to find out which JVM to use. On Windows and Mac
OS there are standard locations for java, but there are too many linux
distributions all with their own location for installing java, so JPype
doesn't even bother with trying to search a few of the most common, instead
it relies on you to set JAVA_HOME.


>
>
>
> 2. "Ok" - I said to myself, and I decided to use REST server, I was
> glad that it runs in single instance, and doesn't needs to stop and
> start for every web request,
>
> Q: AS I understand that using neo4j.py with DJANGO I will run a new
> JVM every request, am I right ? Or nor ?
>

That depends on how you run Django. You will get a new JVM for each Python
process you fork. With CPython running in a web server it is quite common to
fork multiple processes, since CPythons support for multiple threads is
crap. This would be a problem for running Neo4j, which is why I usually
recommend Jython. I have plans for fixing this, but unfortunately I don't
have the time.


>
> 3. Using REST is wonderful and it is suite me with 80% of
> requirements, other 20% I decided to emulate.
> for example:
>
> - To sync deferent user requests with DB, for update/insert/delete
> operations I've decide to do a queue in a relational db, that will
> perform step by step operations, so some part of Transactions was
> solved
>

I'm not sure I quite follow this, but a queue in a relational database
sounds awful. What would you need from the RESTful interface to fulfill
these needs without having to build this thing?


> - I'v wrote a little daemon that picks a task and runs a command.
> - Also I'v created some tests with NetworkX and Graphiz that helps me
> with visualisation of query result
>

Sounds cool. Would you care to share the query visualization?


>
> 4. Python REST implemention is good but it lacks with some traversing
> and indexing functions.
>
> - I'v tried to make some custom queries like:
>
> data = {
>     "order": "depth first",
>     "uniqueness": "node path",
>     "relationships": [
>       { "type": "USER", "direction": "out" },
>       { "type": "OWNES", "direction": "out" },
>       { "type": "USES", "direction": "out" },
>       { "type": "CONTAINS", "direction": "out" },
>     ],
>     "prune evaluator": {
>       "language": "javascript",
>       "body": "if(position.node().hasProperty('username')){\
>         if(position.node().getProperty('username').equals('sergey')){\
>           false;\
>         }else{\
>           true;\
>         }\
>       }else{\
>         false;\
>       }"
>     },
>
>
> response = Request().post(url, data=data)
> if response.status == 200:
>   content = response.body
>     return simplejson.loads(content)
>   else:
>     print response.body
>
>
> Q: first of all I'v faced a lot of problems with "prune evaluator"
>
> 1. I did not found the best way to debug javascript, only "throw"
> inside body can tell me something about var or an object.
> 2. It seems that it is impossible comparisons with relations, maybe
> there is something else but for ex.
>
> ...
> position.node().getRelations()  //returns []
> ....
>

That should throw an exception, since what you would want is
position.node().getRelationsips()


>
> Q: Also it seems impossible to check has current node certain relation
> or not, is it true ?
>

position.node().hasRelationship(SOME_RELATIONSHIP_TYPE)


>
> ...
> enum MyRelationshipTypes implements RelationshipType{\
>  CONTAINED_IN, KNOWS\
> }\
> ...
>
>
> Q: how can I instantiate the RelationshipType inside javascript body,
> or maybe I need to use another script engine ?


MY_REL_TYPE =
org.neo4j.graphdb.DynamicRelationshipType.withName("MY_REL_TYPE")

Not sure how to import that class in those javascripts though. It might be a
good idea to have that injected into the namespace as well.


> It would be nice if
> there will be !MORE! examples about REST traversing, it is very
> powerful tool.
>

I agree!


>
>
> Q: Please who are able, help me with neo4j start, I think I messed up
> something, may be you'll suggest to read some links, or simply help me
> with some examples.
>

Looks to me like you're making pretty good progress :) Just shoot any
questions you have to the mailing list and I'm sure you'll be fine :)


> Q: Maybe it would wiser to learn Java and "Springs" instead of
> tricking with Python, Django and REST

Q: *Dummy question* If it would be a java, could somebody explain me
> the bases work with "springs", the main question is: "Would be spring
> web-application work as a single instance, or I'll need to start and
> stop neo4j engine every request ? "
>

Never, under any circumstances, start and stop Neo4j with every request.
That would kill performance. What you want to do with a web application is
to tie the life cycle of Neo4j to the life cycle of your web server (or web
container in the Java case).

For an example of how to do this, see
http://wiki.neo4j.org/content/Servlets_with_Neo4j
This example does not deal with Spring, only with tying the life cycle of
Neo4j to your container. I'm planning on writing an example that uses spring
as well.


Happy Hacking,
-- 
Tobias Ivarsson <tobias.ivarsson at neotechnology.com>
Hacker, Neo Technology
www.neotechnology.com
Cellphone: +46 706 534857


More information about the User mailing list