Page processing of Neo4j graph data

Source: Internet
Author: User
Tags neo4j

Page processing of Neo4j graph data

First, we will briefly introduce Neo4j. Neo4j is a high-performance NOSQL graphic database that stores structured data on the network rather than in tables, it is an embedded, disk-based, Java persistence engine with full transaction features, but it stores structured data on the Network (called graphs in mathematics) rather than in tables. Neo4j can also be seen as a high-performance graph engine with all the features of mature databases.

Neo4j involves several key object types: Node, Relationship, Path, Direction, and RelationshipType ). Friends can regard Relationship as a connection line. each end of a connection line can only be connected to one Node, and both ends of the connection line must be connected to a Node at the same time; Relationship) has the direction and type features. Node can be associated with multiple other nodes through multiple Relationship, and Node can also be an isolated Node without any connection. A Path contains multiple nodes and Relationship. It is a set of nodes and links. This is a local relationship graph built by the author using Neo4j:

Neo4j_graph

3.1. Neo4j data paging retrieval type

The Neo4j data paging Retrieval Interface uses its own Cypher retrieval statement to construct a Cypher paging retrieval statement for paging processing.

There is no traditional table concept in the Neo4j database. A database can be regarded as a graph. Data paging retrieval will be performed for Node and Relationship, respectively, without paging Retrieval for Path, because basically there is no meaning. You can differentiate search types based on search conditions.

3.1.1 Node (Node) Paging Retrieval

1) unconditionally retrieve Cypher statements

-- Not sorted by attribute
START n = node (*) RETURN n SKIP 0 LIMIT 20

-- Sort by attribute
START n = node (*) RETURN n order by n. name desc skip 0 LIMIT 20

2) retrieve the Cypher statement based on the Property.

-- Perform fuzzy search based on the attribute NAME value
START n = node (*) WHERE n. NAME = ~ '. * Tom *' RETURN n SKIP 0 LIMIT 20

-- Exact search based on the attribute NAME value
START n = node (*) WHERE n. NAME = 'Tom 'RETURN n SKIP 0 LIMIT 20

3) Search for Cypher statements based on Index

-- Note: N_INDEX indicates the index name and USER_NAME indicates the index Key name.

-- Fuzzy search based on index values
-- Multiple formats of fuzzy search.
-- 1. * tom * indicates that USER_NAME contains the tom string
-- 2. * tom indicates that the right side of USER_NAME matches the tom string
-- 3. tom * indicates that the left side of USER_NAME matches the tom string
START n = node: N_INDEX ('user _ NAME: * tom * ') RETURN n SKIP 0 LIMIT 20

-- Exact search based on index values
START n = node: N_INDEX (USER_NAME = 'Tom ') RETURN n SKIP 0 LIMIT 20

4) retrieve the Cypher statement based on the Index and Property attributes.

-- Search by index (Fuzzy) and attribute (Fuzzy)
START n = node: N_INDEX ('user _ NAME: * tom * ') WHERE n. USER_TYPE = ~ '. * Sys *' RETURN n SKIP 0 LIMIT 20

-- Search by index (Fuzzy) and attribute (precise)
START n = node: N_INDEX ('user _ NAME: * tom * ') WHERE n. USER_TYPE = 'system' RETURN n SKIP 0 LIMIT 20

-- Search by index (exact) and attribute (Fuzzy)
START n = node: N_INDEX (USER_NAME = 'Tom ') WHERE n. USER_TYPE = ~ '. * Sys *' RETURN n SKIP 0 LIMIT 20

-- Search by index (exact) and attribute (exact)
START n = node: N_INDEX (USER_NAME = 'Tom ') WHERE n. USER_TYPE = 'system' RETURN n SKIP 0 LIMIT 20

5) Search for Cypher statements based on Label labels

-- The label content is "China"
START n = node (*) MATCH (n: China) RETURN n SKIP 0 LIMIT 20

6) search the Cypher statement based on the Label and Property.

START n = node (*) MATCH (n: China) WHERE n. USER_TYPE = 'system' RETURN n SKIP 0 LIMIT 20

3.1.2 Relationship (Link) Paging Retrieval

1) unconditionally retrieve Cypher statements by PAGE

-- Not sorted by attribute
START r = relationship (*) return distinct (r) SKIP 0 LIMIT 20

-- Sort by attribute
START r = relationship (*) return distinct (r) order by r. name asc skip 0 LIMIT 20

2) retrieve the Cypher statement based on the Property.

-- Perform fuzzy search based on the attribute NAME value
START r = relationship (*) WHERE r. NAME = ~ '. * Tom *' RETURN r SKIP 0 LIMIT 20

-- Exact search based on the attribute NAME value
START r = relationship (*) WHERE r. NAME = 'Tom 'RETURN r SKIP 0 LIMIT 20

3) Search for Cypher statements based on Index

-- Note: R_INDEX indicates the index name and USER_NAME indicates the index Key name.

-- Fuzzy search based on index values
-- Multiple formats of fuzzy search.
-- 1. * tom * indicates that USER_NAME contains the tom string
-- 2. * tom indicates that the right side of USER_NAME matches the tom string
-- 3. tom * indicates that the left side of USER_NAME matches the tom string
START r = relationship (*): R_INDEX ('user _ NAME: * tom * ') RETURN r SKIP 0 LIMIT 20

-- Exact search based on index values
START r = relationship (*): R_INDEX (USER_NAME = 'Tom ') RETURN r SKIP 0 LIMIT 20

4) retrieve the Cypher statement based on the Index and Property attributes.

-- Search by index (Fuzzy) and attribute (Fuzzy)
START r = relationship (*): R_INDEX ('user _ NAME: * tom * ') WHERE r. USER_TYPE = ~ '. * Sys *' RETURN r SKIP 0 LIMIT 20

-- Search by index (Fuzzy) and attribute (precise)
START r = relationship (*): R_INDEX ('user _ NAME: * tom * ') WHERE r. USER_TYPE = 'system' RETURN r SKIP 0 LIMIT 20

-- Search by index (exact) and attribute (Fuzzy)
START r = relationship (*): R_INDEX (USER_NAME = 'Tom ') WHERE r. USER_TYPE = ~ '. * Sys *' RETURN r SKIP 0 LIMIT 20

-- Search by index (exact) and attribute (exact)
START r = relationship (*): R_INDEX (USER_NAME = 'Tom ') WHERE r. USER_TYPE = 'system' RETURN r SKIP 0 LIMIT 20

5) retrieve Cypher statements based on RelationshipType

-- FRIEND is a relational string.
START n = node (*) MATCH n-[r: FRIEND]-() return distinct (r) SKIP 0 LIMIT 20

3.2. Neo4j data paging model class

Import java. io. Serializable;
Import java. text. DecimalFormat;
Import java. util. ArrayList;
Import java. util. List;
Import org. neo4j. graphdb. Node;
Import org. neo4j. graphdb. Relationship;
Import com. hnepri. common. util. LogInfoUtil;
/**
* Description: graph database data paging model class. <Br>
* You can use this class to manage Node data and Relationship data by page.
* Copyright: Copyright (c) 2015 <br>
* Company: smart grid Institute of Henan Electric Power Research Institute <br>
* @ Author shangbingbing 2015-11-01
* @ Version 1.0
*/
Public class GraphPageModel implements Serializable {
Private static final long serialVersionUID = 330347716100946538l;
Private int pageSize = 10;
Private int pageIndex = 1;
Private int prevPageIndex = 1;
Private int nextPageIndex = 1;
Private int pageCount = 0;
Private int pageFirstRowIndex = 1;
Private boolean hasNextPage = true;
Private int totalCount = 0;
Private long startTime = System. currentTimeMillis ();
Private long endTime = System. currentTimeMillis ();
Private List <Node> nodeList = new ArrayList <Node> ();
Private List <Relationship> relationshipList = new ArrayList <Relationship> ();
/**
* Page object constructor
* @ Param pageSize number of records per page
*/
Public GraphPageModel (int pageSize ){
This. pageSize = pageSize;
}
/**
* Retrieve the number of paging records
* @ Return
*/
Public int getPageSize (){
Return pageSize;
}
/**
* Get the serial number of the current page
* @ Return
*/
Public int getPageIndex (){
Return pageIndex;
}
/**
* Set the serial number of the current page
* @ Param pageIndex
*/
Public void setPageIndex (int pageIndex ){
If (pageIndex <= 0 ){
PageIndex = 1;
}
This. pageIndex = pageIndex;
}
/**
* Retrieve the total number of pages
* @ Return
*/
Public int getPageCount (){
If (this. getTotalCount () = 0 ){
This. pageCount = 0;
} Else {
Int shang = this. getTotalCount ()/this. getPageSize ();
Int yu = this. getTotalCount () % this. getPageSize ();
If (yu> 0 ){
Shang + = 1;
}
This. pageCount = shang;
}
Return pageCount;
}
/**
* Obtain the sequence number of the first line on each page.
* @ Return
*/
Public int getPageFirstRowIndex (){
This. pageFirstRowIndex = (this. pageIndex-1) * this. getPageSize () + 1;
Return pageFirstRowIndex;
}
/**
* Obtain the sequence number of the previous page.
* @ Return
*/
Public int getPrevPageIndex (){
If (this. pageIndex> 1 ){
This. prevPageIndex = this. pageIndex-1;
} Else {
This. prevPageIndex = 1;
}
Return prevPageIndex;
}
/**
* Get the sequence number of the next page
* @ Return
*/
Public int getNextPageIndex (){
If (this. pageIndex <this. pageCount ){
This. nextPageIndex = this. pageIndex + 1;
} Else {
This. nextPageIndex = this. pageCount;
}
Return nextPageIndex;
}
/**
* Jump to the next page
*/
Public void nextPage (){
If (this. totalCount = 0 | this. getPageCount () = 0 ){
This. pageIndex = 1;
} Else {
If (this. pageIndex <this. pageCount ){
This. pageIndex = this. pageIndex + 1;
} Else {
This. pageIndex = this. pageCount;
}
}
}
/**
* Jump to the previous page
*/
Public void prevPage (){
If (this. pageIndex> 1 ){
This. pageIndex = this. pageIndex-1;
} Else {
This. pageIndex = 1;
}
}
/**
* Obtain whether the next page exists.
* @ Return
*/
Public boolean isHasNextPage (){
If (this. pageIndex <this. getPageCount ()){
This. hasNextPage = true;
} Else {
This. hasNextPage = false;
}
Return hasNextPage;
}
/**
* Retrieve the total number of records
*/
Public int getTotalCount (){
Return totalCount;
}
/**
* Retrieve the total number of records
* @ Param totalCount
*/
Public void setTotalCount (int totalCount ){
This. totalCount = totalCount;
}
/**
* Initialization Start Time (MS)
*/
Public void initStartTime (){
This. startTime = System. currentTimeMillis ();
}
/**
* Initialization deadline (MS)
*/
Public void initEndTime (){
This. endTime = System. currentTimeMillis ();
}
/**
* Obtain time consumption information in milliseconds
* @ Return
*/
Public String getTimeIntervalByMilli (){
Return String. valueOf (this. endTime-this. startTime) + "millisecond ";
}
/**
* Obtain time consumed in the second format
* @ Return
*/
Public String getTimeIntervalBySecond (){
Double interval = (this. endTime-this. startTime)/1000.0;
DecimalFormat df = new DecimalFormat ("#.##");
Return df. format (interval) + "seconds ";
}
/**
* Print the time information.
*/
Public void printTimeInfo (){
LogInfoUtil. printLog ("Start Time:" + this. startTime );
LogInfoUtil. printLog ("Deadline:" + this. endTime );
LogInfoUtil. printLog ("Time consumed:" + this. getTimeIntervalBySecond ());
}
/**
* Retrieve the Node search result list
* @ Return
*/
Public List <Node> getNodeList (){
Return nodeList;
}
/**
* Retrieve the list of Relationship search results
* @ Return
*/
Public List <Relationship> getRelationshipList (){
Return relationshipList;
}
}


In the model class, nodeList and relationshipList are used to store Node and Relationship respectively. When Node information is retrieved by PAGE, getNodeList () is used to read Node information. When Relationship is retrieved by PAGE, getRelationshipList () read the Relationship information.


3.3. Neo4j data paging Interface Method
First, we first design a general interface method for executing Cypher search statements, and convert the search results (mainly Node, Relationship, and Path objects) to the Propertyies list.


/**
* Run the Cypher search statement to encapsulate the search results in the Properties list.
* @ Param query cypher retrieval statement
* @ Param params cypher: set of search statement Parameters
* @ Return
*/
Public List <Properties> executeQuery (String query, Map <String, Object> params ){
List <Properties> propertiesList = new ArrayList <Properties> ();
If (StringUtils. isBlank (query )){
Return propertiesList;
}
ExecutionEngine executionEngine = new ExecutionEngine (this. getGraphDatabaseService ());
ExecutionResult result = null;
If (params = null | params. size () = 0 ){
Result = executionEngine.exe cute (query );
} Else {
Result = executionEngine.exe cute (query, params );
}
For (Map <String, Object> row: result ){
Properties properties = new Properties ();
For (Entry <String, Object> column: row. entrySet ()){
Properties. put (column. getKey (), column. getValue ());
}
PropertiesList. add (properties );
}
Return propertiesList;
}

The following uses unconditional paging Node Information Retrieval as an example to describe the design idea of the interface method. The Code is as follows:

/**
* Retrieve Node information by page.
* @ Param pageModel: The paging model object. It cannot be blank.
* @ Param orders: Sorting attribute field.
* @ Return
*/
Public GraphPageModel queryNodes (GraphPageModel pageModel, GOrderBy... orders ){
If (pageModel = null ){
PageModel = new GraphPageModel (10 );
}
PageModel. getNodeList (). clear ();
PageModel. getRelationshipList (). clear ();

// Calculate the total number of rows
String query = "START n = node (*) RETURN count (*) AS NODE_COUNT ";
List <Properties> resultList = this.exe cuteQuery (query );
If (resultList = null | resultList. size () = 0 ){
Return pageModel;
}
For (Properties properties: resultList ){
Int nodeCount = Integer. valueOf (properties. get ("NODE_COUNT"). toString ());
PageModel. setTotalCount (nodeCount );
}

// Organize the sorting Field Information
String strGOrderBy = "";
If (orders! = Null & orders. length> 0 ){
StrGOrderBy = "order ";
For (GOrderBy order: orders ){
StrGOrderBy + = String. format ("n. % s,", order. getPropertyName (), order. getOrderType (). toUpperCase ());
}
StrGOrderBy = strGOrderBy. substring (0, strGOrderBy. length ()-1 );
}

Int skipCount = (pageModel. getPageIndex ()-1) * pageModel. getPageSize ();
Int limitCount = pageModel. getPageSize ();
Query = String. format ("START n = node (*) RETURN n AS NODE_ENTRY % s SKIP % s LIMIT % s", strGOrderBy, skipCount, limitCount );
List <Properties> list = this.exe cuteQuery (query );
For (Properties properties: list ){
PageModel. getNodeList (). add (Node) properties. get ("NODE_ENTRY "));
}

Return pageModel;
}

Neo4j details: click here
Neo4j: click here

Recommended reading:

Neo4j generates test data

How Neo4j runs

Neo4j High Availability Configuration

Neo4J graph database practice series

Graph database practice series (1)-introduction and installation of Neo4J

Graph database practice series (II) -- Neo4J Spatial Data Storage

Graph database practice series (iii) -- REST integration of Neo4j Spatial

This article permanently updates the link address:

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.