2013-08-06 34 views
1

我已經運行下面的查詢找到一個特定的人有一定的「距離」以內的親屬:春數據/ Neo4j的路徑長度設置

@Query("start person=node({0}), relatives=node:__types__(className='Person') match p=person-[:PARTNER|CHILD*]-relatives where LENGTH(p) <= 2*{1} return distinct relatives") 
Set<Person> getRelatives(Person person, int distance); 

的2 * {1}來自一個人們之間的概念性「跳躍」被表示爲兩個節點 - 一個人和一個夥伴關係。

到目前爲止,這在測試人羣中一直很好。現在我正在轉向實際的數據,它包含了從1百萬到1百萬的大小,並且這是永遠的(也來自Web界面中的數據瀏覽器)。

假設成本是從裝載到一切ancestors,我重寫了查詢作爲數據瀏覽器測試:

start person=node(385716) match p=person-[:PARTNER|CHILD*1..10]-relatives where relatives.__type__! = 'Person' return distinct relatives 

而且工作正常,在幾分之一秒相同的數據存儲。但是,當我想要把它放回的Java:

@Query("start person=node({0}) match p=person-[:PARTNER|CHILD*1..{1}]-relatives where relatives.__type__! = 'Person' return relatives") 
Set<Person> getRelatives(Person person, int distance); 

這是行不通的:

[...] 
Nested exception is Properties on pattern elements are not allowed in MATCH. 
"start person=node({0}) match p=person-[:PARTNER|CHILD*1..{1}]-relatives where relatives.__type__! = 'Neo4jPerson' return relatives" 
             ^

有沒有把一個路徑長度限制在那裏的一個更好的辦法?我寧願不使用where,因爲這將涉及加載所有路徑,可能會加載數百萬個節點,而我只需要深度爲10的節點。這大概會讓我沒有更好。

任何想法將不勝感激!


邁克爾來救援!

我的解決辦法:

public Set<Person> getRelatives(final Person person, final int distance) { 

    final String query = "start person=node(" + person.getId() + ") " 
     + "match p=person-[:PARTNER|CHILD*1.." + 2 * distance + "]-relatives " 
     + "where relatives.__type__! = '" + Person.class.getSimpleName() + "' " 
     + "return distinct relatives"; 

    return this.query(query); 

    // Where I would previously instead have called 
    // return personRepository.getRelatives(person, distance); 
} 

public Set<Person> query(final String q) { 

    final EndResult<Person> result = this.template.query(q, MapUtil.map()).to(Neo4jPerson.class); 
    final Set<Person> people = new HashSet<Person>(); 

    for (final Person p : result) { 
     people.add(p); 
    } 

    return people; 
} 

其中運行速度很快!

+0

不要直接使用id,而是使用參數,類名相同。否則,您將在運行時丟失查詢緩存,因爲它必須重新解析每個查詢! –

回答

1

就快:)

你的第一個查詢是一個完整的圖形掃描,從而有效地加載整個數據庫到內存中,並通過該模式匹配翻出所有節點多次。

所以它不會很快,它會返回巨大的數據集,不知道這是你想要的。

第二個查詢看起來不錯,唯一的問題是您無法參數化可變長度關係的最小 - 最大值。由於對查詢優化/緩存的影響。

因此,現在你必須使用template.query()或不同的查詢方法在你的倉庫中獲取不同的最大值。

+0

感謝您的解釋 - 並感謝您的所有工作! :d – KendallV