<h1>LogiSima - Neo4j database support</h1>
<p>
    This module allows you to use an embedded <a href="http://neo4j.org">Neo4j database</a> and managed your model with annotation (like JPA). This module is similar as <a href="http://www.springsource.org/spring-data/neo4j">Spring data neo4j</a>, it's the same philosophy.  
</p>

<h2><a>Installation</a></h2>
<h3><a>Enabled Neo4j module</a></h3>
<h4><a>For play &lt; 1.2</a></h4>
<p>
    In the conf/application.conf file, enable LogiSima Neo4j module with this line :
</p>
<pre>
    <code>
    # The logisima play cas module
    module.neo4j=${play.path}/modules/neo4j-1.0RC1
    </code>
</pre>
<h3><a>For play >= 1.2</a></h3>
<p>
    In the conf/dependencies.yml file, enable LogiSima Neo4j module depency by adding this line :
</p>
<pre>
    <code>
        require:    
        &nbsp;&nbsp;- play -> neo4j 1.0RC1
    </code>
</pre>

<h3><a>Module configuration</a></h3>
<p>
    In the conf/application.conf file, you can specify the path of neo4j embedded database by adding this line (by default it's "db") :
</p>
<pre>
    <code>
        neo4j.path=dbProd
    </code>
</pre>

<h2><a>How to use it</a></h2>

<h3><a>Declare your model</a></h3>
<p>
    To create a Model you just have to create a class that extend <code> play.modules.neo4j.model.Neo4jModel</code>, that's all !<br/>
    <u>Exemple :</u>
</p>
<pre>
    <code>
        public class User extends Neo4jModel {
            public String     login;
            public String     email;
            public String     firstname;
            public String     lastname;
        }
    </code>
</pre>
<h4>Supported types</h4>
<p>
    Neo4j doesn't support all kind of attributes (see http://docs.neo4j.org/chunked/snapshot/graphdb-neo4j-properties.html), so do my module. This is a list of supported (and tested) type :
</p>
 <ul>
	<li>String</li>
    <li>Long (the object not the primitive type, see issue #11)</li>
    <li>java.util.Date</li>
    <li>Integer</li>
    <li>Boolean</li>
    <li>play.db.jpa.Blob</li>
</ul>
<p>
	<strong>NB:</strong>In general, use Object instead of primitive type (Float vs float, Integer vs int, Boolean vs boolean ...).
</p>
    
<h4>Basics methods</h4>
<p>
    Models come with some basics methods :
</p>
<ul>
	<li><code>getByKey(Long key)</code> : in neo4j there is no id field but a key one. It's the unique identifier of the object. This key is automaticly generate by the module. You can retrieve an Model simly by calling the <code>getByKey</code> method. Exemple : <code>User user = User.getByKey(3);</code></li>
    <li><code>save()</code> : Save and index the object to the database</li>
    <li><code>delete()</code> : Delete the object to the database</li>
    <li><code>findAll()</code> : Retrieve all model object into the database. Becarefull there is no limitationwith this method. So if you have a million of object, this method return a million of object. Exemple : <code>List<User> user = User.findAll();</code> </li>
    <li><code>queryIndex()</code> : Do a lucene query on a specific index, and return a list of Object that match your query. Exemple : <code>List<User> user = User.queryIndex("lastname", "lastname:*s* AND firstname:*s*");</code> </li>
</ul>

<h3><a>Add a relation to your model</a></h3>
<p>
    To create a relation between a node and others, you have to :
    <ul>
        <li>Create a field of type <code>java.util.List</code></li>
        <li>Annotate your filed this the <code>@Neo4jRelatedTo</code> annotation and specify the name of the relation</li>
    </ul>
    <u>Exemple :</u>
</p>
<pre>
    <code>
        public class User extends Neo4jModel {
            public String     login;
            public String     email;
            public String     firstname;
            public String     lastname;
            
            @Neo4jRelatedTo("IS_FRIEND")
            public List<User> friends;
        }
    </code>
</pre>

<p>
With Neo4jRelatedTo annotation, you can also defined some attributes :
</p> 
<ul>
    <li><strong>lazy :</strong> like hibernate, you can do lazy loading for relation. By default, it's value is "true" to avoid circular reference and avoid loop that produce "Java Heap Space".</li>
    <li><strong>direction :</strong>to specified the direction of the relation. By default, it's "OUTGOING", but you can change it to "INCOMING". Direction "BOTH is not implemented !!!</li>
</ul>


<h3><a>Create an index</a></h3>
<p>
    You can create a neo4j index simply by adding an annotation on fields : <code>@Neo4jIndex</code><br/>
    <u>Exemple :</u>
</p>
<pre>
    <code>
        public class User extends Neo4jModel {
            public String     login;
            public String     email;
            
            @Neo4jIndex("name")
            public String     firstname;
            
            @Neo4jIndex("name")
            public String     lastname;
            
            @Neo4jRelatedTo("IS_FRIEND")
            public List<User> friends;
        }
    </code>
</pre>
<p>
    This will create an index named <code>name</code>, and for each user when we save it, firstname and lastanme value will be index into <code>name</code> index.
</p>
<p>
    Moreover, you can customize lucene configuration with the annotation :
    <ul>
        <li><strong>type</strong>: <strong>exact</strong> is the default value, it uses a Lucene keyword analyzer. <strong>fulltext</strong> type uses a white-space tokenizer in its analyzer</li>
        <li><strong>lowerCase</strong>: This parameter goes together with type: fulltext and converts values to lower case during both additions and querying, making the index case insensitive. Defaults value is true.</li>
    </ul>
</p>

<h3><a>Import / Export your database</a></h3>

<h4><a>Export</a></h4>
<p>
    Neo4j module comes with a command line tool to export your database into an yml file. To do it, you just have to type this line into a console :
</p>
<pre>
    <code>play neo4j:export</code>
</pre>
<p>By default, this will generate a file into your <code>conf</code> application folder with the name <code>data.yml</code>. Of course, you can change it. Type <code>play neo4j:help</code> to khnow how to do it.</p>

<h4><a>Import</a></h4>
<p>
    You can import an yml file into your database. To do it, yo can choose between :
</p>
<ul>
    <li>Commmand line, by calling <code>play neo4j:import</code></li>
    <li>Java, by calling the <code>load(String filename)</code> method from <code>play.modules.neo4j.util.Fixtures</code> class. It will be usefull for unit test !</li>    
</ul>

<h4><a>Yml format</a></h4>
<p>
    The yml format for this module is very simple. There is two kind of "yml object" : model & relation.<br/>
</p>
<p>
For model, the format is the same as play! standard. First line contains the model class and an identifier. Other lne are simply attribute name with their value.
<br/><u>Exemple :</u>
</p>
<pre>
    <code>
        User(User_2):
         login: ben
         email: logisima@gmail.com
         firstname: Benoît
         lastname: SIMARD
    </code>
</pre>
<p>
For relation, there is a special format. All relation must begin with <code>Relation(id)</code> where id is a unique identifier of the relation.<br/>
After, all relation must have three attributes :
</p>
<ul>
    <li><strong>Type</strong> Correspond to the name of the relation</li>
    <li><strong>From</strong> is the identifier of the start node</li>
    <li><strong>To</strong> is the identifier of the end node</li>
</ul>
<p><u>Exemple :</u></p>
<pre>
    <code>
        Relation(15):
         Type: IS_A_COLLEAGE
         From: User_2
         To: User_1
    </code>
</pre>

<h3><a>See neo4j console</a></h3>

<p>Neo4j get a console to browse the database and to get usefull informations. To see it, just type this url into your browser, and youo will see the console :</p>
<code>http://localhost:9000/@neo4j/console</code>
<p><strong>NB:</strong>Console is only avaible when play! is in DEV mode !</p>