2017-05-05 110 views
0

我嘗試使用neo4j和彈簧數據分頁百萬的對象。我的程序執行兩次查詢: 第一次匹配數據。第二次統計所有匹配我的限制的元素。但最後一個查詢需要很長時間。查詢需要很長的時間,而計數


這是PAGINATE功能的某些部分:

@Autowired 
Neo4jOperations template;` 


StringBuilder query = new StringBuilder(" match (n:Domain) where n.isPrincipale={isPrincipale} "); 
mapOfVars.put("isPrincipale", true); 
    if (request.getParameterMap().containsKey("mydom") 
     && !request.getParameter("mydom").isEmpty()) { 
      query.append(" and n.domain =~ {mydom}"); 
      mapOfVars.put("mydom",".*(?i)"+request.getParameter("mydom")+".*"); 
} 

的probleme是在這裏:

iTotalRecords = Integer.valueOf((template.query(query.toString() + " return count(n) as count", mapOfVars)).queryResults().iterator().next().get("count").toString()); 

計數我得到的匹配結果後:

query.append(" 
    return n.domain as domain, n.hasDmarc as dmarc , 
    n.spf_action as spf, n.updatedAt as updatedAt , 
    n.existValue as exst , id(n) as id 
    skip {start} limit {displayCount}"); 
mapOfVars.put("start", iDisplayStart); 
mapOfVars.put("displayCount", iDisplayCount); 

Iterable<Map<String, Object>> domains = template.query(query.toString(), mapOfVars); 
+1

請分享更多的細節,否則,你不能幫助。有快速計數的方法,但沒有提供詳細信息... –

+0

你可以檢查現在編輯後的請。 –

回答

2

如果你沒有索引(或唯一性co nstraint):Domain(isPrincipale),那麼neo4j將不得不掃描所有Domain節點以找到匹配的節點。

要創建索引,運行此查詢:

CREATE INDEX ON :Domain(isPrincipale); 

注意,雖然,使用索引可以幫助最如果只有相同標記的節點的比例相對較小有isPrincipale值要比賽。不幸的是,由於isPrincipale的值是一個布爾值(因此只有2個可能的值),索引可能沒有多大幫助。

[更新]

的主要問題是,你正在執行一個完整的查詢來獲取每一次所有匹配Domain節點(兩者計數他們時,並在每個分頁步驟)。這顯然非常昂貴。只要獲得所有匹配的節點,然後在本地進行計數和分頁就會更好(速度快)。

另一種加快速度的方法(但可能比上述的程度要小)是消除昂貴的正則表達式字符串比較來找到匹配的節點。如果事先知道一組可能的mydom字符串,則可以將這些字符串與適當的Domain節點之間的關係存儲在數據庫中。例如,您可以創建DomainName節點,並在其中的每個節點與相應的Domain節點之間創建HAS_DOMAIN關係。這樣,你的第一個代碼片段可以成爲這個,並導致更快的查詢:

@Autowired 
Neo4jOperations template;` 

StringBuilder query = new StringBuilder(); 
String mydom = request.getParameter("mydom"); 
if (mydom != null && !mydom.isEmpty()) { 
    query.append("MATCH (:DomainName {name: $mydom})-[:HAS_DOMAIN]->(n:Domain) "); 
    mapOfVars.put("mydom", mydom); 
} else { 
    query.append("MATCH (n:Domain) "); 
} 
query.append("WHERE n.isPrincipale=$isPrincipale") 
mapOfVars.put("isPrincipale", true); 
+0

已經創建。我的查詢也可以包含對任何域的屬性的限制。所以我不想在所有屬性上創建索引 –

+0

在這種情況下,你對cahe有什麼看法?因爲主要問題是neo4j在計數時檢查所有域。 –

+0

查看我更新的答案。 – cybersam