2014-10-19 99 views
4

使用Neo4j的2.1.x的,讓我們假設這個查詢,返回的是買了車用戶123的朋友:Cypher /我應該使用WITH子句將值傳遞給下一個MATCH嗎?

MATCH (u1:User("123"))-[:KNOWS]-(friend) 
MATCH (friend)-[:BUYS]->(c:Car) 
RETURN friend 

在這種article,它是寫關於WITH條款:

所以,它是如何工作的?那麼,基本上只是一個流,因爲它可以是懶惰的 (和返回一樣懶),將結果傳遞給 下一個查詢。

這樣看來我要轉變這樣的查詢:

​​

要這樣呢?或者當前版本的Cypher已經處理了MATCH鏈接,同時通過它們傳遞值?

回答

7

您在查詢的前期提供的更準確的起點,會更高效。

你的第一個匹配不太準確,它確實會使用遍歷匹配器來匹配所有可能的關係。

採取以下Neo4j的控制檯例如:http://console.neo4j.org/r/jsx71g

而且你的第一個查詢誰看起來像這樣的例子:

MATCH (n:User { login: 'nash99' })-[:KNOWS]->(friend) 
RETURN count(*) 

你可以看到在前期dbhits量:

Execution Plan 

    ColumnFilter 
     | 
     +EagerAggregation 
     | 
     +Filter 
      | 
      +TraversalMatcher 

    +------------------+------+--------+-------------+-----------------------------------------+ 
    |   Operator | Rows | DbHits | Identifiers |         Other | 
    +------------------+------+--------+-------------+-----------------------------------------+ 
    |  ColumnFilter | 1 |  0 |    |     keep columns count(*) | 
    | EagerAggregation | 1 |  0 |    |           | 
    |   Filter | 8 | 320 |    | Property(n,login(2)) == { AUTOSTRING0} | 
    | TraversalMatcher | 160 | 201 |    |    friend, UNNAMED32, friend | 
    +------------------+------+--------+-------------+-----------------------------------------+ 
Total database accesses: 521 

如果你使用更準確的起點,當你從這一點開始時,你是這條道路的王者,看看這個例子中的查詢ND看到其中的差別在DB點擊:

Execution Plan 

ColumnFilter 
    | 
    +EagerAggregation 
    | 
    +SimplePatternMatcher 
     | 
     +Filter 
     | 
     +NodeByLabel 

+----------------------+------+--------+------------------------+-----------------------------------------+ 
|    Operator | Rows | DbHits |   Identifiers |         Other | 
+----------------------+------+--------+------------------------+-----------------------------------------+ 
|   ColumnFilter | 1 |  0 |      |     keep columns count(*) | 
|  EagerAggregation | 1 |  0 |      |           | 
| SimplePatternMatcher | 8 |  0 | n, friend, UNNAMED51 |           | 
|    Filter | 1 |  40 |      | Property(n,login(2)) == { AUTOSTRING0} | 
|   NodeByLabel | 20 |  21 |     n, n |         :User | 
+----------------------+------+--------+------------------------+-----------------------------------------+ 

Total database accesses: 61 

因此終止您的查詢,我會做這樣的事情:

MATCH (n:User { login: 'nash99' }) 
WITH n 
MATCH (n)-[:KNOWS]->(friend)-[:BUYS]->(c:Car) 
RETURN friend 

你也可以指定朋友不能是相同的用戶:

MATCH (n:User { login: 'nash99' }) 
    WITH n 
    MATCH (n)-[:KNOWS]->(friend)-[:BUYS]->(c:Car) 
    WHERE NOT friend.id = n.id 
    RETURN friend 

注意,就有了上面的查詢之間沒有差異,在DB命中事項如下:

MATCH (n:User { login: 'nash99' }) 
WITH n 
MATCH (n)-[:KNOWS]->(friend) 
WITH friend 
MATCH (friend)-[:BUYS)->(c:Car) 
RETURN (friend) 

我建議您使用neo4j控制檯查看顯示上述信息的結果詳細信息。

如果您需要爲測試快速建立圖表的原型,可以使用Graphgen,在cypher語句中導出圖形,並在neo4j控制檯中加載這些語句。

這裏是鏈接到graphgen代I用於http://graphgen.neoxygen.io/?graph=29l9XJ0HxJ2pyQ

克里斯

+0

我在查詢中犯了一個錯誤控制檯。它應該是:MATCH(u1:User {id:「123」}) - [:KNOWS] - (friend)'。你寫道:「你的第一場比賽不太準確」。爲什麼?因爲我正在使用帶'id'屬性索引的標籤.... – Mik378 2014-10-19 19:56:11

+0

是的,您正在使用標籤,但您不是匹配標籤化節點,而是完整模式。看看結果的詳細信息,它使用遍歷匹配器,因此它會遍歷圖形以匹配您的模式,我的建議是使用標籤索引而不是 – 2014-10-19 20:00:19

+0

哦...我認爲這種行爲將是:「第一個節點被標記,所以我(密碼引擎)首先匹配它,然後,我將遍歷指定的路徑「。如果我很明白,你說的行爲就是我的情況:「讓我們遍歷路徑,並且我將只保留與索引匹配的節點」...明顯地導致完整的遍歷匹配。我很好理解嗎? – Mik378 2014-10-19 20:04:28

相關問題