background
In some forums or news recently saw a Neo4j , good database for processing graphics. It is said that is well suited to do some join relational query, so taking the time to also looked under the relevant documents, give yourself to be a technical reserve.
process
Before delving into the study, the first on the Internet to find a bit of a learning document summarizes the others, standing on the shoulders of others is always the fastest, most effective learning.
For the figure of some basic concepts:
- node: Node
- relationships: relationship, that is, edges in the graph, attention is directed edges
- properties: property, for node / relationship can be set up property
- Traversal: graph traversal tool
- Indexes: Index
node (Node)
- Each node can have multiple relationships (relationship) between a plurality of nodes and
- Single node may be provided a plurality of keys (Key, Value) of the attribute properties
relationships (relationship)
- Each relationship will include a startNode and endNode
- Each relationship can be provided a plurality of keys (Key, Value) of the attribute properties
- May be defined corresponding relationship between the type of relation (RelationshipType)
* DynamicRelationshipType dynamic relationship type
* XXXRelationshipType static relationship types (RelationshipType implements interface)
Traversal (traversing)
cross: http://wiki.neo4j.org/content/Traversal
one example:
- Traverser trav = swedenNode.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH,
- new ReturnableEvaluator()
- {
- public boolean isReturnableNode( TraversalPosition pos )
- {
- return !pos.isStartNode() && pos.lastRelationshipTraversed().isType( CUSTOMER_TO_ORDER );
- }
- },
- LIVES_IN, Direction.INCOMING,
- CUSTOMER_TO_ORDER, Direction.OUTGOING );
- // iterate over traverser...<span style="white-space: normal;">
- </span>
Traverser trav = swedenNode.traverse(Order.DEPTH_FIRST, StopEvaluator.END_OF_GRAPH,
new ReturnableEvaluator()
{
public boolean isReturnableNode( TraversalPosition pos )
{
return !pos.isStartNode() && pos.lastRelationshipTraversed().isType( CUSTOMER_TO_ORDER );
}
},
LIVES_IN, Direction.INCOMING,
CUSTOMER_TO_ORDER, Direction.OUTGOING );
// iterate over traverser...
Order: traversal algorithm corresponding to FIG.
- DEPTH_FIRST: depth-first search is to find the first node, recursive been looking down until after no suitable node before backtracking
- BREADTH_FIRST: BFS
- OUTGOING: the edge
- INCOMING: the edge
- BOTH: Guming Si Yee
- DEPTH_ONE: After more than one depth stop
- END_OF_GRAPH: no suitable results and stop
- ALL_BUT_START_NODE: exclude initial node
- ALL: return all nodes
- A node information
- Information on an incoming Relationship
- Search Depth
- So far the number of nodes that satisfy the condition
Indexs (index)
are stored in neo4j independently for each node / relationship / property, it is the natural order. In order to support some scenarios, such as for relational database queries based on the primary key name corresponding to the person node, ordinary Traversal difficult to meet such a demand, and people are not used to solve this thing. Therefore neo4j it leads to the concept of an index.
Early versions of the index is to use a IndexService ( http://wiki.neo4j.org/content/Indexing_with_IndexService )
one example:
- GraphDatabaseService graphDb = new EmbeddedGraphDatabase( "path/to/neo4j-db" );
- IndexService index = new LuceneIndexService( graphDb );
- Node andy = graphDb.createNode();
- Node larry = graphDb.createNode();
- andy.setProperty( "name", "Andy Wachowski" );
- andy.setProperty( "title", "Director" );
- larry.setProperty( "name", "Larry Wachowski" );
- larry.setProperty( "title", "Director" );
- index.index( andy, "name", andy.getProperty( "name" ) );
- index.index( andy, "title", andy.getProperty( "title" ) );
- index.index( larry, "name", larry.getProperty( "name" ) );
- index.index( larry, "title", larry.getProperty( "title" ) );
GraphDatabaseService graphDb = new EmbeddedGraphDatabase( "path/to/neo4j-db" ); IndexService index = new LuceneIndexService( graphDb ); Node andy = graphDb.createNode(); Node larry = graphDb.createNode(); andy.setProperty( "name", "Andy Wachowski" ); andy.setProperty( "title", "Director" ); larry.setProperty( "name", "Larry Wachowski" ); larry.setProperty( "title", "Director" ); index.index( andy, "name", andy.getProperty( "name" ) ); index.index( andy, "title", andy.getProperty( "title" ) ); index.index( larry, "name", larry.getProperty( "name" ) ); index.index( larry, "title", larry.getProperty( "title" ) );
IndexService as an external component is extended definition.
Now the official documentation is recommended to use Integrated Index Framework
- The official document: http://docs.neo4j.org/chunked/stable/indexing.html
- Migration scenarios: http://wiki.neo4j.org/content/Transitioning_To_Index_Framework
- IndexManager index = graphDb.index();
- Index<Node> actors = index.forNodes( "actors" );
- Index<Node> movies = index.forNodes( "movies" );
- RelationshipIndex roles = index.forRelationships( "roles" );
IndexManager index = graphDb.index(); Index<Node> actors = index.forNodes( "actors" ); Index<Node> movies = index.forNodes( "movies" ); RelationshipIndex roles = index.forRelationships( "roles" );
Query Syntax (Cyphe Query Language)
neo4j own search algorithm based on graph theory, to achieve a set of query language parsing, provides some common aggregate functions (max, sum, min, count, etc.).
Syntax example:
- Join query:
- start n=(1) match (n)-[:BLOCKS]->(x) return x
- Where conditions:
- start n=(2, 1) where (n.age < 30 and n.name = "Tobias") or not(n.name = "Tobias") return n
- Aggregation function:
- start n=(2,3,4) return avg(n.property)
- Order:
- start n=(1,2,3) return n order by n.name DESC
- Paging:
- start n=(1,2,3,4,5) return n order by n.name skip 1 limit 2
Join查询: start n=(1) match (n)-[:BLOCKS]->(x) return x Where条件: start n=(2, 1) where (n.age < 30 and n.name = "Tobias") or not(n.name = "Tobias") return n 聚合函数: start n=(2,3,4) return avg(n.property) Order: start n=(1,2,3) return n order by n.name DESC 分页: start n=(1,2,3,4,5) return n order by n.name skip 1 limit 2
Call example:
- db = new ImpermanentGraphDatabase();
- engine = new ExecutionEngine( db );
- CypherParser parser = new CypherParser();
- ExecutionEngine engine = new ExecutionEngine(db);
- Query query = parser.parse( "start n=(0) where 1=1 return n" );
- ExecutionResult result = engine.execute( query );
- assertThat( result.columns(), hasItem( "n" ) );
- Iterator<Node> n_column = result.columnAs( "n" );
- assertThat (asIterable (n_column), hasItem (db.getNodeById ( 0 )));
- assertThat( result.toString(), containsString("Node[0]") );
db = new ImpermanentGraphDatabase(); engine = new ExecutionEngine( db ); CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(db); Query query = parser.parse( "start n=(0) where 1=1 return n" ); ExecutionResult result = engine.execute( query ); assertThat( result.columns(), hasItem( "n" ) ); Iterator<Node> n_column = result.columnAs( "n" ); assertThat( asIterable( n_column ), hasItem(db.getNodeById(0)) ); assertThat( result.toString(), containsString("Node[0]") );
other
Expansibility
Not yet see a corresponding expansion of the program
Availability (HA mechanism)
Ha neo4j currently support a simple mechanism, it is managed by the zookeeper.
Its mechanism is very simple, is responsible for neo4j server heartbeat detection by the zookeeper.
1. Discover hung up after the master, initiates an election (not seen the source code, reckoned to achieve the election will be very simple, according to the corresponding serverid, take the smallest id as the new master).
2. Insert the new broadcast to all slave master, this time in the electoral process, does not accept the write request corresponding to the (all returns an exception)
3. The new machine joins the cluster, as a slave to the master will communicate, synchronize two data content provider (if the current slave of the new master tid ratio will produce a data conflict requiring a manual intervention)
Problems:
Timeliness 1. zookeeper heartbeat detection, the default delay of three minutes (because there packet retry)
2. During the master election, write request can not be processed directly returns an exception (although master of timing of the elections will be relatively end, but the client is not friendly enough)
Points for improvement:
1. To provide the client api, provide a mechanism for controlling one failover retry.
Console page
neo4j supports two modes of embedded and standalone deployment, deployed at neo4j independent deployment server, the effect is as follows:
Graphics management background, you can see aspects of relationships between nodes
rest interface api, graphics and offers several ways pure data:
Other documents
- http://wiki.neo4j.org/content/FAQ
- http://wiki.neo4j.org/content/Getting_Started_With_Neo4j_Server
- neo4j-manual-stable.pdf
Original Address: https: //www.iteye.com/blog/agapple-1128400