Neo4j應用

CQL函數

1. 字符串函數

功能 描述
UPPER 將所有字母改爲大寫
LOWER 將所有字母改爲小寫
SUBSTRING 將獲取指定範圍的子字符串
REPLACE 替換一個字符串的子字符串
match (p:Person) return ID(p),LOWER(p.character)

2. 聚合函數

聚集功能 描述
COUNT 它返回由MATCH命令返回的行數
MAX 它從MATCH命令返回的一組行返回最大值
MIN 它返回由MATCH命令返回的一組行的最小值
SUM 它返回由MATCH命令返回的所有行的求和
AVG 它返回由MATCH命令返回的所有行的平均值

示例:

match (p:Person) return max(p.money)

3. 關係函數

功能 描述
STARTNODE 用於知道關係的開始節點
ENDNODE 用於知道關係的結束節點
ID 用於知道關係的ID
TYPE 用於知道字符串表示中的一個關係的TYPE

示例:

match p=(:Person {name:"範閒"})-[r:Couple]-(:Person) return ENDNODE(r)

match p=(:Person {name:"範閒"})-[r:Couple]-(:Person) return type(r)

4. 返回最短路徑

shortestPath函數

示例:

match p=shortestPath((person:Person {cid:1})-[*]-(person2:Person {cid:8})) return length(p),nodes(p)

CQL多深度關係節點

1. 使用with關鍵字

查詢三層級關係節點如下:with可以將前面查詢結果作爲後面查詢條件

match (na:Person)-[re]->(nb:Person) where na.name="範閒" WITH na,re,nb match (nb:Person)-
[re2]->(nc:Person) return na,re,nb,re2,nc

2. 直接拼接關係節點查詢

match data=(na:Person{name:"範閒"})-[re]->(nb:Person)-[re2]->(nc:Person) return data

3. 使用深度運算符

-[:TYPE*minHops..maxHops]-

minHops代表最小深度,maxHops代表最大深度。

match data=(na:Person{cid:1})-[*1..2]-(:Person) return data

事務

Neo4j支持ACID特性

  • 所有對Neo4j數據庫的數據修改操作都必須封裝在事務中
  • 默認的isolation level是READ_COMMITTED
  • 死鎖保護已經內置到核心事務管理。
  • 除特殊說明,Neo4j的API操作都是線程安全的,Neo4j數據庫的操作也就沒有必要使用外部的同步方法。

索引

Neo4j支持在節點或關係的屬性上建立索引,以提高應用程序的性能。可以在Match或where等運算符上使用這些索引改進SQL的執行。

  1. 單一索引
CREATE INDEX ON :Label(property)

示例:

create index on:Person(name)
  1. 複合索引
create index on:Person(age,gender)
  1. 全文索引

常規索引只能對字符串進行精確匹配或前後綴索引,而全文索引可以匹配字符串任何位置的詞語。

使用db.index.fulltext.createNodeIndex和db.index.fulltext.createRelationshipIndex可以分別爲節點和關係創建全文索引。在創建索引時,必須指定唯一的名稱,用於查詢和刪除索引時要引用。

call db.index.fulltext.createNodeIndex("索引名",[Label,Label],[屬性,屬性])

示例:

call db.index.fulltext.createNodeIndex("nameAndDescription",["Person"],["name",
"description"])

call db.index.fulltext.queryNodes("nameAndDescription", "範閒") YIELD node, score
RETURN node.name, node.description, score
  1. 查看索引
call db.indexes 或:schema
  1. 刪除索引
DROP INDEX ON :Person(name)
DROP INDEX ON :Person(age, gender)
call db.index.fulltext.drop("nameAndDescription")

約束

作用:唯一性約束用於避免重複記錄

1. 創建唯一性約束

CREATE CONSTRAINT ON (變量:<label_name>) ASSERT 變量.<property_name> IS UNIQUE

示例:

create constraint on(person:Person) assert person.name is unique

2. 刪除唯一性約束

drop constraint on (person:Person) assert person.name is unique

3. 查看約束

call db.constraints
#或
:schema

Neo4j服務管理

1. 備份和恢復

  1. 備份之前先停止服務
 bin/neo4j stop
  1. 備份命令
bin/neo4j-admin dump --database=graph.db --to=/usr/local/qyn.dump

然後啓動服務,刪除所有數據。然後在停止服務,準備恢復

match (p)-[r]-() delete p,r
  1. 恢復命令
bin/neo4j-admin load --from=/usr/local/qyn.dump --database=graph.db --force

注意:運行數據備份可能會警告

WARNING: Max 1024 open files allowed, minimum of 40000 recommended. See the Neo4j manual

編輯這個文件:vim /etc/security/limits.conf,在文件最後面加上這段,修改最大打開文件限制,在重啓服務器就行了。

*        soft   nofile     65535
*        hard   nofile     65535

2. Neo4j調優

2.1 調整neo4j配置文件

# neo4j初始堆內存
dbms.memory.heap.initial_size=512m
# 最大堆內存
dbms.memory.heap.max_size=512m
# pagecache大小,官方建議設爲:(總內存-dbms.memory.heap.max_size)/2
dbms.memory.pagecache.size=10g

2.2 數據預熱

match (n)
optional match (n)-[r]->()
return count(n.name)+count(r)
  1. 使用執行計劃命令優化

有如下兩個命令:

  • Explain :解釋機制,加入該關鍵字的Cypher語句可以預覽執行的過程但是不實際執行
  • Profile:畫像機制,查詢中使用該關鍵字能夠看到執行計劃詳細內容,還能看到查詢的結果

示例:

profile match (p:Person {name:"範閒"}) return p

需要關注指標:

關注指標:

estimated rows: 需要被掃描行數的預估值

dbhits: 實際運行結果的命中績效

Neo4j 程序訪問

1. 數據庫訪問方式

Neo4j訪問有兩種方式:

  • 嵌入式數據庫
  • 服務器模式(通過REST的訪問)

嵌入式數據庫

嵌入式Neo4j數據庫是性能的最佳選擇,通過指定數據存儲的路徑以編程的方式訪問。我們選擇嵌入式數據庫有如下的原因:

  • 使用java作爲編程語言
  • 應用程序獨立
  • 程序追求很高的性能

服務器模式

Neo4j Server是相互操作性、安全性和監控的最佳選擇。實際上,REST接口允許所有現代平臺和編程語言與它進行交互操作。此外,作爲獨立應用程序,他比嵌入式配置更安全(客戶端的故障不會影響服務器),更易於監控。而且可以使用任意編程語言以REST的方式訪問數據庫。

2. Java客戶端訪問

2.1 嵌入式模式

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j</artifactId>
    <version>3.5.5</version>
</dependency>

新增數據

 public static void add(){
        GraphDatabaseService graphDb= new GraphDatabaseFactory().newEmbeddedDatabase(databaseDirectory);
        System.out.println("database load");
        Transaction tx = graphDb.beginTx();
        Node node = graphDb.createNode();
        node.setProperty("name","張三");
        node.setProperty("character","A");
        node.setProperty("money",2330);
        node.addLabel(() -> "Person");
        tx.success();
        tx.close();
        graphDb.shutdown();
    }

查詢數據

public static void query(){
        GraphDatabaseService graphDb= new GraphDatabaseFactory().newEmbeddedDatabase(databaseDirectory);
        System.out.println("database load");
        String cql="match (a:Person) where a.money < $money return a";
        Map<String,Object> paramerters= new HashMap<>();
        paramerters.put("money",2500);
        Transaction tx=graphDb.beginTx();
        Result result = graphDb.execute(cql, paramerters);
        while (result.hasNext()){
            Map<String, Object> row = result.next();
            for (String key : result.columns()){
                Node nd = (Node)row.get(key);
                System.out.printf("%s = %s:%s%n",key,nd.getProperties("name"),nd.getProperties("money"));
            }
        }
        tx.success();
        tx.close();
        graphDb.shutdown();
    }

2.2 服務器模式

<dependency>
    <groupId>org.neo4j</groupId>
    <artifactId>neo4j-ogm-bolt-driver</artifactId>
    <version>3.2.10</version>
</dependency>

查詢示例:

public static void query(){
    Driver driver = GraphDatabase.driver("bolt://192.168.56.115:7687", AuthTokens.basic("neo4j", "123456"));
    Session session = driver.session();
    String cql="match (a:Person) where a.money > $money return a.name as name,a.money as money order by a.money";
    Result result = session.run(cql, Values.parameters("money", 400));
    while (result.hasNext()){
        Record record = result.next();
        System.out.println(record.get("name").asString()+"  "+record.get("money").asDouble());
    }
    session.close();
    driver.close();

}

SpringBoot 整合Neo4j

  1. 引入依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
  1. 編寫配置文件
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=123456
spring.data.neo4j.uri= bolt://192.168.56.115:7687
  1. 建立實體類
@NodeEntity
@Data
public class Person {
    @Id
    @GeneratedValue
    private Long id;

    private Integer cid;

    private String name;

    private String character;

    private Double money;

    private Integer gender;

    private Integer age;

    private String description;

    @Relationship(type = "Friend",direction = Relationship.OUTGOING)
    private Set<Person> relationPersons;

  1. 編寫數據持久層
@Repository
public interface PersonRepository extends Neo4jRepository<Person,Long> {

    @Query("match(p:Person) where p.money > {0} return p")
    List<Person> personList(Double money);

    @Query("match p=shortestPath((person:Person {name:{0}}) - [*1..2] - (person2:Person {name:{1}})) return p ")
    List<Person> shortestPath(String startName,String endName);
}
  1. 測試
Iterable<Person> all = personRepository.findAll();
System.out.println(all);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章