Package org.neo4j.cypherdsl

Source Code of org.neo4j.cypherdsl.CypherCookbookTest

/**
* Copyright (c) 2002-2013 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.neo4j.cypherdsl;

import static org.neo4j.cypherdsl.CypherQuery.abs;
import static org.neo4j.cypherdsl.CypherQuery.allNodes;
import static org.neo4j.cypherdsl.CypherQuery.as;
import static org.neo4j.cypherdsl.CypherQuery.coalesce;
import static org.neo4j.cypherdsl.CypherQuery.collect;
import static org.neo4j.cypherdsl.CypherQuery.count;
import static org.neo4j.cypherdsl.CypherQuery.create;
import static org.neo4j.cypherdsl.CypherQuery.distinct;
import static org.neo4j.cypherdsl.CypherQuery.has;
import static org.neo4j.cypherdsl.CypherQuery.id;
import static org.neo4j.cypherdsl.CypherQuery.identifier;
import static org.neo4j.cypherdsl.CypherQuery.in;
import static org.neo4j.cypherdsl.CypherQuery.isNull;
import static org.neo4j.cypherdsl.CypherQuery.literal;
import static org.neo4j.cypherdsl.CypherQuery.lookup;
import static org.neo4j.cypherdsl.CypherQuery.max;
import static org.neo4j.cypherdsl.CypherQuery.min;
import static org.neo4j.cypherdsl.CypherQuery.node;
import static org.neo4j.cypherdsl.CypherQuery.nodesById;
import static org.neo4j.cypherdsl.CypherQuery.not;
import static org.neo4j.cypherdsl.CypherQuery.order;
import static org.neo4j.cypherdsl.CypherQuery.p;
import static org.neo4j.cypherdsl.CypherQuery.param;
import static org.neo4j.cypherdsl.CypherQuery.path;
import static org.neo4j.cypherdsl.CypherQuery.range;
import static org.neo4j.cypherdsl.CypherQuery.round;
import static org.neo4j.cypherdsl.CypherQuery.start;
import static org.neo4j.cypherdsl.CypherQuery.sum;
import static org.neo4j.cypherdsl.CypherQuery.type;
import static org.neo4j.cypherdsl.CypherQuery.value;
import static org.neo4j.cypherdsl.Order.ASCENDING;
import static org.neo4j.cypherdsl.Order.DESCENDING;

import org.junit.Test;
import org.neo4j.cypherdsl.grammar.Start;
import org.neo4j.cypherdsl.query.Query;

/**
* Construct Cypher queries corresponding to the Cypher Cookbook in the manual
*/
public class CypherCookbookTest extends AbstractCypherTest
{
    @Test
    public void test5_1_1()
    {
        // This test shows how to do partial queries. When the Query from toQuery() is passed into a new CypherQuery
        // it is cloned, so any modifications do not affect the original query

        Query query = start( lookup( "n", "node_auto_index", "name", "User1" ) ).
                match( node( "n" ).out( "hasRoleInGroup" ).node( "hyperEdge" ).out( "hasGroup" ).node( "group" ),
                        node( "hyperEdge" ).out( "hasRole" ).node( "role" ) ).toQuery();

        assertQueryEquals( CYPHER + "START n=node:node_auto_index(name=\"User1\") MATCH (n)-[:hasRoleInGroup]->" +
                "(hyperEdge)-[:hasGroup]->(group),(hyperEdge)-[:hasRole]->(role) WHERE group.name=\"Group2\" RETURN " +
                "role.name",
                CypherQuery.continueQuery( query, Start.class ).starts().
                        where( identifier( "group" ).string( "name" ).eq( "Group2" ) ).
                        returns( identifier( "role" ).string( "name" ) ).
                        toString() );

        assertQueryEquals( CYPHER + "START n=node:node_auto_index(name=\"User1\") MATCH (n)-[:hasRoleInGroup]->" +
                "(hyperEdge)-[:hasGroup]->(group),(hyperEdge)-[:hasRole]->(role) RETURN role.name," +
                "group.name ORDER BY role.name ASCENDING",
                CypherQuery.continueQuery( query, Start.class ).starts().
                        returns( identifier( "role" ).property( "name" ), identifier( "group" ).property( "name" ) ).
                        orderBy( order( identifier( "role" ).string( "name" ), ASCENDING ) ).
                        toString() );
    }

    @Test
    public void test5_1_2()
    {
        Identifier u1 = identifier( "u1" );
        Identifier u2 = identifier( "u2" );
        Identifier hyperEdge1 = identifier( "hyperEdge1" );
        Identifier group = identifier( "group" );
        Identifier role = identifier( "role" );
        Identifier hyperEdge2 = identifier( "hyperEdge2" );
        assertQueryEquals( CYPHER + "START u1=node:node_auto_index(name=\"User1\")," +
                "u2=node:node_auto_index(name=\"User2\") " +
                "MATCH (u1)-[:hasRoleInGroup]->(hyperEdge1)-[:hasGroup]->(group)," +
                "(hyperEdge1)-[:hasRole]->(role)," +
                "(u2)-[:hasRoleInGroup]->(hyperEdge2)-[:hasGroup]->(group)," +
                "(hyperEdge2)-[:hasRole]->(role) " +
                "RETURN group.name,count(role) " +
                "ORDER BY group.name ASCENDING",
                start( lookup( u1, identifier( "node_auto_index" ), identifier( "name" ), literal( "User1" ) ),
                        lookup( u2, identifier( "node_auto_index" ), identifier( "name" ), literal( "User2" ) ) ).
                        match( node( u1 )
                                .out( "hasRoleInGroup" )
                                .node( hyperEdge1 )
                                .out( "hasGroup" )
                                .node( group ),
                                node( hyperEdge1 ).out( "hasRole" ).node( role ),
                                node( u2 )
                                        .out( "hasRoleInGroup" )
                                        .node( hyperEdge2 )
                                        .out( "hasGroup" )
                                        .node( group ),
                                node( hyperEdge2 ).out( "hasRole" ).node( role ) ).
                        returns( group.property( "name" ), count( role ) ).
                        orderBy( order( group.property( "name" ), ASCENDING ) )
                        .toString() );
    }

    @Test
    public void test5_1_3()
    {
        assertQueryEquals( CYPHER + "START u1=node:node_auto_index(name=\"User1\")," +
                "u2=node:node_auto_index(name=\"User2\") " +
                "MATCH (u1)-[:hasRoleInGroup]->(hyperEdge1)-[:hasGroup]->(group)," +
                "(hyperEdge1)-[:hasRole]->(role)," +
                "(u2)-[:hasRoleInGroup]->(hyperEdge2)-[:hasGroup]->(group)," +
                "(hyperEdge2)-[:hasRole]->(role) " +
                "RETURN group.name,count(role) " +
                "ORDER BY group.name ASCENDING",
                start( lookup( "u1", "node_auto_index", "name", "User1" ), lookup( "u2", "node_auto_index", "name",
                        "User2" ) ).
                        match( node( "u1" ).out( "hasRoleInGroup" )
                                .node( "hyperEdge1" )
                                .out( "hasGroup" )
                                .node( "group" ),
                                node( "hyperEdge1" ).out( "hasRole" ).node( "role" ),
                                node( "u2" ).out( "hasRoleInGroup" )
                                        .node( "hyperEdge2" )
                                        .out( "hasGroup" )
                                        .node( "group" ),
                                node( "hyperEdge2" ).out( "hasRole" ).node( "role" ) ).
                        returns( identifier( "group" ).property( "name" ), count( identifier( "role" ) ) ).
                        orderBy( order( identifier( "group" ).property( "name" ), Order.ASCENDING ) ).toString()
        );
    }

    @Test
    public void test5_2_1()
    {
        assertQueryEquals( CYPHER + "START joe=node:node_auto_index(name=\"Joe\") OPTIONAL MATCH (joe)-[:knows]->(friend)" +
                "-[:knows]->(friend_of_friend),(joe)-[r:knows]->(friend_of_friend) WHERE r is null RETURN " +
                "friend_of_friend.name,count(*) ORDER BY count(*) DESCENDING,friend_of_friend.name",
                start( lookup( "joe", "node_auto_index", "name", "Joe" ) ).
                        match( node( "joe" ).out( "knows" ).node( "friend" )
                                .out( "knows" ).node( "friend_of_friend" ),
                                node( "joe" ).out( "knows" ).as( "r" ).node( "friend_of_friend" ) ).optional().
                        where( isNull( identifier( "r" ) ) ).
                        returns( identifier( "friend_of_friend" ).property( "name" ), count() ).
                        orderBy( order( count(), DESCENDING ), identifier( "friend_of_friend" ).property( "name" ) ).
                        toString() );
    }

    @Test
    public void test5_3_1()
    {
        assertQueryEquals( CYPHER + "START place=node:node_auto_index(name=\"CoffeShop1\") MATCH (place)" +
                "<-[:favorite]-(person)-[:favorite]->(stuff) RETURN stuff.name,count(*) ORDER BY count(*) DESCENDING," +
                "stuff.name",
                start( lookup( "place", "node_auto_index", "name", "CoffeShop1" ) ).
                        match( node( "place" ).in( "favorite" ).node( "person" ).out( "favorite" ).node( "stuff" ) ).
                        returns( identifier( "stuff" ).property( "name" ), count() ).
                        orderBy( order( count(), DESCENDING ), identifier( "stuff" ).property( "name" ) ).
                        toString() );

        assertQueryEquals( CYPHER + "START place=node:node_auto_index(name=\"CoffeShop1\") MATCH (place)-[:tagged]->" +
                "(tag)<-[:tagged]-(otherPlace) RETURN otherPlace.name,collect(tag.name) ORDER BY otherPlace.name " +
                "DESCENDING",
                start( lookup( "place", "node_auto_index", "name", "CoffeShop1" ) ).
                        match( node( "place" ).out( "tagged" ).node( "tag" ).in( "tagged" ).node( "otherPlace" ) ).
                        returns( identifier( "otherPlace" ).property( "name" ), collect( identifier( "tag" ).property
                                ( "name" ) ) ).
                        orderBy( order( identifier( "otherPlace" ).property( "name" ), DESCENDING ) ).
                        toString() );
    }

    @Test
    public void test5_3_2()
    {
        assertQueryEquals( CYPHER + "START place=node:node_auto_index(name=\"CoffeeShop1\") MATCH (place)-[:tagged]->" +
                "(tag)<-[:tagged]-(otherPlace) RETURN otherPlace.name,collect(tag.name) ORDER BY otherPlace.name " +
                "DESCENDING",
                start( lookup( "place", "node_auto_index", "name", "CoffeeShop1" ) ).
                        match( node( "place" ).out( "tagged" ).node( "tag" ).in( "tagged" ).node( "otherPlace" ) ).
                        returns( identifier( "otherPlace" ).property( "name" ), collect( identifier( "tag" ).property
                                ( "name" ) ) ).
                        orderBy( order( identifier( "otherPlace" ).property( "name" ), DESCENDING ) ).toString() );
    }

    @Test
    public void test5_4_1()
    {
        assertQueryEquals( CYPHER + "START me=node:node_auto_index(name=\"Joe\") MATCH (me)-[:favorite]->(stuff)" +
                "<-[:favorite]-(person) WHERE not((me)-[:friend]-(person)) RETURN person.name," +
                "count(stuff) ORDER BY count(stuff) DESCENDING",
                start( lookup( "me", "node_auto_index", "name", "Joe" ) ).
                        match( node( "me" ).out( "favorite" ).node( "stuff" ).in( "favorite" ).node( "person" ) ).
                        where( not( node( "me" ).both( "friend" ).node( "person" ) ) ).
                        returns( identifier( "person" ).property( "name" ), count( identifier( "stuff" ) ) ).
                        orderBy( order( count( identifier( "stuff" ) ), DESCENDING ) ).
                        toString() );
    }

    @Test
    public void test5_5_1()
    {
        assertQueryEquals( CYPHER + "START me=node(5),other=node(4,3) " +
                "OPTIONAL MATCH pGroups=(me)-[:member_of_group]->(mg)<-[:member_of_group]-(other)," +
                "pMutualFriends=(me)-[:knows]->(mf)<-[:knows]-(other) " +
                "RETURN other.name AS name," +
                "count(DISTINCT pGroups) AS mutualGroups," +
                "count(DISTINCT pMutualFriends) AS mutualFriends ORDER BY mutualFriends DESCENDING",
                start( nodesById( "me", 5 ), nodesById( "other", 4, 3 ) ).
                        match( path( "pGroups", node( "me" ).out( "member_of_group" ).node( "mg" ).in(
                                "member_of_group" ).node( "other" ) ),
                                path( "pMutualFriends", node( "me" ).out( "knows" ).node( "mf" ).in(
                                        "knows" ).node( "other" ) ) ).optional().
                        returns( as( identifier( "other" ).property( "name" ), "name" ),
                                as( count( distinct( identifier( "pGroups" ) ) ), "mutualGroups" ),
                                as( count( distinct( identifier( "pMutualFriends" ) ) ), "mutualFriends" ) ).
                        orderBy( order( identifier( "mutualFriends" ), DESCENDING ) ).toString() );
    }

    @Test
    public void test5_6_1()
    {
        assertQueryEquals( CYPHER + "START me=node(9) " +
                "MATCH (me)-[:favorite]->(myFavorites)-[:tagged]->(tag)<-[:tagged]-(theirFavorites)<-[:favorite]-" +
                "(people) " +
                "WHERE not(me=people) " +
                "RETURN people.name AS name,count(*) AS similar_favs " +
                "ORDER BY similar_favs DESCENDING",
                start( nodesById( "me", 9 ) ).
                        match( node( "me" ).out( "favorite" ).node( "myFavorites" ).out( "tagged" ).node( "tag" ).in(
                                "tagged" ).node( "theirFavorites" ).in( "favorite" ).node( "people" ) ).
                        where( not( identifier( "me" ).eq( identifier( "people" ) ) ) ).
                        returns( as( identifier( "people" ).property( "name" ), "name" ), as( count(),
                                "similar_favs" ) ).
                        orderBy( order( identifier( "similar_favs" ), DESCENDING ) ).toString() );
    }

    @Test
    public void test5_7_1()
    {
        assertQueryEquals( CYPHER + "START me=node:node_auto_index(name=\"Joe\") " +
                "MATCH (me)-[r1]->(other)-[r2]->(me) " +
                "WHERE type(r1)=type(r2) and type(r1)=~\"FOLLOWS|LOVES\" " +
                "RETURN other.name,type(r1)",
                start( lookup( "me", "node_auto_index", "name", "Joe" ) ).
                        match( node( "me" ).out().as( "r1" ).node( "other" ).out().as( "r2" ).node( "me" ) ).
                        where( type( identifier( "r1" ) ).eq( type( identifier( "r2" ) ) )
                                .and( type( identifier( "r1" ) ).regexp( "FOLLOWS|LOVES" ) ) ).
                        returns( identifier( "other" ).property( "name" ), type( identifier( "r1" ) ) ).toString() );
    }

    @Test
    public void test5_7_1_1()
    {
        assertQueryEquals( CYPHER + "START me=node:node_auto_index(name=\"Joe\") " +
                "MATCH (me)-[r1]->(other)-[r2]->(me) " +
                "WHERE type(r1)=type(r2) and type(r1)=~{param1} " +
                "RETURN other.name,type(r1)",
                start( lookup( "me", "node_auto_index", "name", "Joe" ) ).
                        match( node( "me" ).out().as( "r1" ).node( "other" ).out().as( "r2" ).node( "me" ) ).
                        where( type( identifier( "r1" ) ).eq( type( identifier( "r2" ) ) )
                                .and( type( identifier( "r1" ) ).regexp( param( "param1" ) ) ) ).
                        returns( identifier( "other" ).property( "name" ), type( identifier( "r1" ) ) ).toString() );
    }

    @Test
    public void test5_8_1()
    {
        assertQueryEquals( CYPHER + "START origin=node(1) " +
                "MATCH (origin)-[r1:KNOWS|WORKSAT]-(c)-[r2:KNOWS|WORKSAT]-(candidate) " +
                "WHERE type(r1)=type(r2) and not((origin)-[:KNOWS]-(candidate)) " +
                "RETURN origin.name AS origin,candidate.name AS candidate,sum(round(r2.weight+" +
                "coalesce(r2.activity,0)*2)) AS boost " +
                "ORDER BY boost DESCENDING " +
                "LIMIT 10",
                start( nodesById( "origin", 1 ) ).
                        match( node( "origin" ).both( "KNOWS", "WORKSAT" ).as( "r1" ).node( "c" ).both( "KNOWS",
                                "WORKSAT" ).as( "r2" ).node( "candidate" ) ).
                        where( type( identifier( "r1" ) ).eq( type( identifier( "r2" ) ) ).and( not( node( "origin" )
                                .both( "KNOWS" ).node( "candidate" ) ) ) ).
                        returns( as( identifier( "origin" ).property( "name" ), "origin" ),
                                as( identifier( "candidate" ).property( "name" ), "candidate" ),
                                as( sum( round( identifier( "r2" ).property( "weight" ).add( coalesce( identifier(
                                        "r2" )
                                        .property( "activity" )
                                        , literal( 0 ) )
                                        .times( 2 ) ) ) ), "boost" ) ).
                        orderBy( order( identifier( "boost" ), DESCENDING ) ).
                        limit( 10 ).toString() );
    }

    @Test
    public void test5_8_1_1()
    {
        assertQueryEquals( CYPHER + "START origin=node(1) " +
                "MATCH (origin)-[r1:KNOWS|WORKSAT]-(c)-[r2:KNOWS|WORKSAT]-(candidate) " +
                "WHERE type(r1)=type(r2) and not((origin)-[:KNOWS]-(candidate)) " +
                "RETURN origin.name AS origin,candidate.name AS candidate,sum(round(r2.weight+" +
                "coalesce(r2.activity,0)*2)) AS boost " +
                "ORDER BY boost DESCENDING " +
                "LIMIT {limitParam}",
                start( nodesById( "origin", 1 ) ).
                        match( node( "origin" ).both( "KNOWS", "WORKSAT" ).as( "r1" ).node( "c" ).both( "KNOWS",
                                "WORKSAT" ).as( "r2" ).node( "candidate" ) ).
                        where( type( identifier( "r1" ) ).eq( type( identifier( "r2" ) ) ).and( not( node( "origin" )
                                .both( "KNOWS" ).node( "candidate" ) ) ) ).
                        returns( as( identifier( "origin" ).property( "name" ), "origin" ),
                                as( identifier( "candidate" ).property( "name" ), "candidate" ),
                                as( sum( round( identifier( "r2" ).property( "weight" ).add( coalesce( identifier(
                                        "r2" )
                                        .property( "activity" )
                                        , literal( 0 ) )
                                        .times( 2 ) ) ) ), "boost" ) ).
                        orderBy( order( identifier( "boost" ), DESCENDING ) ).
                        limit( "limitParam" ).toString() );
    }

    @Test
    public void test5_9_1()
    {
        assertQueryEquals( CYPHER + "START a=node(1) " +
                "MATCH (a)--(b) " +
                "WITH a,count(DISTINCT b) AS n " +
                "MATCH (a)--()-[r]-()--(a) " +
                "RETURN n,count(DISTINCT r) AS r",
                start( nodesById( "a", 1 ) ).
                        match( node( "a" ).both().node( "b" ) ).
                        with( identifier( "a" ), as( count( distinct( identifier( "b" ) ) ), "n" ) ).
                        match( node( "a" ).both().node().both().as( "r" ).node().both().node( "a" ) ).
                        returns( identifier( "n" ), as( count( distinct( identifier( "r" ) ) ), "r" ) ).toString() );
    }

    @Test
    public void test5_10_1()
    {
        assertQueryEquals( CYPHER + "CREATE (center) " +
                "FOREACH(x in range(1,10)| CREATE (leaf),(center)-[:X]->(leaf)) " +
                "RETURN id(center) AS id",
                create( node( "center" ) ).
                        forEach( in( identifier( "x" ), range( 1, 10 ) ).create( node( "leaf" ),
                                node( "center" ).out( "X" ).node( "leaf" ) ) ).
                        returns( as( id( identifier( "center" ) ), "id" ) ).toString() );
    }

    @Test
    public void test5_10_2()
    {
        assertQueryEquals( CYPHER + "CREATE (center) " +
                "FOREACH(x in range(1,10)| CREATE (leaf {count:x}),(center)-[:X]->(leaf)) " +
                "WITH center " +
                "MATCH (large_leaf)<--(center)-->(small_leaf) " +
                "WHERE large_leaf.count=small_leaf.count+1 " +
                "CREATE (small_leaf)-[:X]->(large_leaf) " +
                "WITH center,min(small_leaf.count) AS min,max(large_leaf.count) AS max " +
                "MATCH (first_leaf)<--(center)-->(last_leaf) " +
                "WHERE first_leaf.count=min and last_leaf.count=max " +
                "CREATE (last_leaf)-[:X]->(first_leaf) " +
                "RETURN id(center) AS id",
                create( node( "center" ) ).
                        forEach( in( "x", range( 1, 10 ) ).create( node( "leaf" ).values( value( "count",
                                identifier( "x" ) ) ), node( "center" ).out( "X" ).node( "leaf" ) ) ).
                        with( identifier( "center" ) ).
                        match( node( "large_leaf" ).in().node( "center" ).out().node( "small_leaf" ) ).
                        where( identifier( "large_leaf" ).property( "count" ).eq( identifier( "small_leaf" ).property
                                ( "count" ).add( 1 ) ) ).
                        create( node( "small_leaf" ).out( "X" ).node( "large_leaf" ) ).
                        with( identifier( "center" ), as( min( identifier( "small_leaf" ).property( "count" ) ),
                                "min" ), as( max( identifier( "large_leaf" ).property( "count" ) ), "max" ) ).
                        match( node( "first_leaf" ).in().node( "center" ).out().node( "last_leaf" ) ).
                        where( identifier( "first_leaf" ).property( "count" ).eq( identifier( "min" ) ).and(
                                identifier( "last_leaf" ).property( "count" ).eq( identifier( "max" ) ) ) ).
                        create( node( "last_leaf" ).out( "X" ).node( "first_leaf" ) ).
                        returns( as( id( identifier( "center" ) ), "id" ) ).toString() );
    }

    @Test
    public void test5_10_3()
    {
        assertQueryEquals( CYPHER + "CREATE (center) " +
                "FOREACH(x in range(1,10)| CREATE (leaf {count:x}),(center)-[:X]->(leaf)) " +
                "WITH center " +
                "MATCH (leaf1)<--(center)-->(leaf2) " +
                "WHERE id(leaf1)<id(leaf2) " +
                "CREATE (leaf1)-[:X]->(leaf2) " +
                "WITH center " +
                "MATCH (center)-[r]->() " +
                "DELETE center,r",
                create( node( "center" ) ).
                        forEach( in( "x", range( 1, 10 ) ).create( node( "leaf" ).values( value( "count",
                                identifier( "x" ) ) ), node( "center" ).out( "X" ).node( "leaf" ) ) ).
                        with( identifier( "center" ) ).
                        match( node( "leaf1" ).in().node( "center" ).out().node( "leaf2" ) ).
                        where( id( "leaf1" ).lt( id( "leaf2" ) ) ).
                        create( node( "leaf1" ).out( "X" ).node( "leaf2" ) ).
                        with( identifier( "center" ) ).
                        match( node( "center" ).out().as( "r" ).node() ).
                        delete( identifier( "center" ), identifier( "r" ) ).toString() );
    }

    @Test
    public void test5_10_4()
    {
        assertQueryEquals( CYPHER + "CREATE (center) " +
                "FOREACH(x in range(1,10)| CREATE (leaf1),(leaf2),(center)-[:X]->(leaf1),(center)-[:X]->(leaf2)," +
                "(leaf1)-[:X]->(leaf2)) " +
                "RETURN id(center) AS id",
                create( node( "center" ) ).
                        forEach( in( "x", range( 1, 10 ) ).create( node( "leaf1" ), node( "leaf2" ),
                                node( "center" ).out( "X" ).node( "leaf1" ), node( "center" ).out( "X" ).node(
                                "leaf2" ), node( "leaf1" ).out( "X" ).node( "leaf2" ) ) ).
                        returns( as( id( identifier( "center" ) ), "id" ) ).toString() );
    }

    @Test
    public void test5_12_1()
    {
        assertQueryEquals( CYPHER + "CREATE (root)-[:LINK]->(root) RETURN root",
                create( node( "root" ).out( "LINK" ).node( "root" ) ).returns( identifier( "root" ) ).toString() );
    }

    @Test
    public void test5_12_2()
    {
        assertQueryEquals( CYPHER + "START root=node(4) " +
                "MATCH (root)-[:LINK*0..]->(before),(after)-[:LINK*0..]->(root),(before)-[old:LINK]->(after) " +
                "WHERE before.value<25 and 25<after.value " +
                "CREATE (before)-[:LINK]->({value:25})-[:LINK]->(after) " +
                "DELETE old",
                start( nodesById( "root", 4 ) ).
                        match( node( "root" ).out( "LINK" ).hops( 0, null ).node( "before" ),
                                node( "after" ).out( "LINK" ).hops( 0, null ).node( "root" ),
                                node( "before" ).out( "LINK" ).as( "old" ).node( "after" ) ).
                        where( identifier( "before" ).property( "value" ).lt( 25 ).and( literal( 25 ).lt(
                                identifier( "after" ).property( "value" ) ) ) ).
                        create( node( "before" ).out( "LINK" ).node().values( value( "value",
                                25 ) ).out( "LINK" ).node( "after" ) ).
                        delete( identifier( "old" ) ).toString() );
    }

    @Test
    public void test5_12_3()
    {
        assertQueryEquals( CYPHER + "START root=node(4) " +
                "MATCH (root)-[:LINK*0..]->(before),(before)-[delBefore:LINK]->(del)-[delAfter:LINK]->(after)," +
                "(after)-[:LINK*0..]->(root) " +
                "WHERE del.value=10 " +
                "CREATE (before)-[:LINK]->(after) " +
                "DELETE del,delBefore,delAfter",
                start( nodesById( "root", 4 ) ).
                        match( node( "root" ).out( "LINK" ).hops( 0, null ).node( "before" ),
                                node( "before" ).out( "LINK" ).as( "delBefore" ).node( "del" ).out( "LINK" ).as(
                                        "delAfter" ).node( "after" ),
                                node( "after" ).out( "LINK" ).hops( 0, null ).node( "root" ) ).
                        where( identifier( "del" ).property( "value" ).eq( 10 ) ).
                        create( node( "before" ).out( "LINK" ).node( "after" ) ).
                        delete( identifier( "del" ), identifier( "delBefore" ), identifier( "delAfter" ) ).toString() );
    }

    @Test
    public void test5_13_1()
    {
        assertQueryEquals( CYPHER + "START root=node:node_auto_index(name=\"Root\") " +
                "MATCH rootPath=(root)-[:`2010`]->()-[:`12`]->()-[:`31`]->(leaf),(leaf)-[:VALUE]->(event) " +
                "RETURN event.name " +
                "ORDER BY event.name ASCENDING",
                start( lookup( "root", "node_auto_index", "name", "Root" ) ).
                        match( path( "rootPath", node( "root" ).out( "2010" ).node().out( "12" ).node().out( "31" )
                                .node( "leaf" ) ), node( "leaf" ).out( "VALUE" ).node( "event" ) ).
                        returns( identifier( "event" ).property( "name" ) ).
                        orderBy( order( identifier( "event" ).property( "name" ), ASCENDING ) ).toString() );
    }

    @Test
    public void test5_13_2()
    {
        assertQueryEquals( CYPHER + "START root=node:node_auto_index(name=\"Root\") " +
                "MATCH startPath=(root)-[:`2010`]->()-[:`12`]->()-[:`31`]->(startLeaf)," +
                "endPath=(root)-[:`2011`]->()-[:`01`]->()-[:`03`]->(endLeaf)," +
                "valuePath=(startLeaf)-[:NEXT*0..]->(middle)-[:NEXT*0..]->(endLeaf)," +
                "values=(middle)-[:VALUE]->(event) " +
                "RETURN event.name " +
                "ORDER BY event.name ASCENDING",
                start( lookup( "root", "node_auto_index", "name", "Root" ) ).
                        match( path( "startPath", node( "root" ).out( "2010" ).node().out( "12" ).node().out( "31" )
                                .node( "startLeaf" ) ),
                                path( "endPath", node( "root" ).out( "2011" ).node().out( "01" ).node().out( "03" )
                                        .node( "endLeaf" ) ),
                                path( "valuePath", node( "startLeaf" ).out( "NEXT" ).hops( 0,
                                        null ).node( "middle" ).out( "NEXT" ).hops( 0, null ).node( "endLeaf" ) ),
                                path( "values", node( "middle" ).out( "VALUE" ).node( "event" ) ) ).
                        returns( identifier( "event" ).property( "name" ) ).
                        orderBy( order( identifier( "event" ).property( "name" ), ASCENDING ) ).toString() );
    }

    @Test
    public void test5_13_3()
    {
        assertQueryEquals( CYPHER + "START root=node:node_auto_index(name=\"Root\") " +
                "MATCH commonPath=(root)-[:`2011`]->()-[:`01`]->(commonRootEnd)," +
                "startPath=(commonRootEnd)-[:`01`]->(startLeaf)," +
                "endPath=(commonRootEnd)-[:`03`]->(endLeaf)," +
                "valuePath=(startLeaf)-[:NEXT*0..]->(middle)-[:NEXT*0..]->(endLeaf)," +
                "values=(middle)-[:VALUE]->(event) " +
                "RETURN event.name " +
                "ORDER BY event.name ASCENDING",
                start( lookup( "root", "node_auto_index", "name", "Root" ) ).
                        match( path( "commonPath", node( "root" ).out( "2011" ).node().out( "01" ).node(
                                "commonRootEnd" ) ),
                                path( "startPath", node( "commonRootEnd" ).out( "01" ).node( "startLeaf" ) ),
                                path( "endPath", node( "commonRootEnd" ).out( "03" ).node( "endLeaf" ) ),
                                path( "valuePath", node( "startLeaf" ).out( "NEXT" ).hops( 0,
                                        null ).node( "middle" ).out( "NEXT" ).hops( 0, null ).node( "endLeaf" ) ),
                                path( "values", node( "middle" ).out( "VALUE" ).node( "event" ) ) ).
                        returns( identifier( "event" ).property( "name" ) ).
                        orderBy( order( identifier( "event" ).property( "name" ), ASCENDING ) ).toString() );
    }

    @Test
    public void test5_14_1()
    {
        assertQueryEquals( CYPHER + "START me=node(*) " +
                "MATCH (me)-[r1:ATE]->(food)<-[r2:ATE]-(you) " +
                "WHERE has(me.name) and me.name=\"me\" " +
                "WITH me,count(DISTINCT r1) AS H1,count(DISTINCT r2) AS H2,you " +
                "MATCH (me)-[r1:ATE]->(food)<-[r2:ATE]-(you) " +
                "RETURN sum((1-abs(r1.times/H1-r2.times/H2))*(r1.times+r2.times)/(H1+H2)) AS similarity",
                start( allNodes( "me" ) ).
                        match( node( "me" ).out( "ATE" ).as( "r1" ).node( "food" ).in( "ATE" ).as( "r2" ).node( "you"
                        ) ).
                        where( has( identifier( "me" ).property( "name" ) ).and( identifier( "me" ).property( "name" )
                                .eq( "me" ) ) ).
                        with( identifier( "me" ), as( count( distinct( identifier( "r1" ) ) ), "H1" ),
                                as( count( distinct( identifier( "r2" ) ) ), "H2" ), identifier( "you" ) ).
                        match( node( "me" ).out( "ATE" ).as( "r1" ).node( "food" ).in( "ATE" ).as( "r2" ).node( "you"
                        ) ).
                        returns( as( sum( p( literal( 1 ).subtract( abs( identifier( "r1" ).property( "times" )
                                .divideBy( identifier( "H1" ) )
                                .subtract( identifier( "r2" ).property( "times" )
                                        .divideBy( identifier( "H2" ) ) ) ) ) )
                                .
                                        times( p( identifier( "r1" ).property( "times" )
                                                .add( identifier( "r2" ).property( "times" ) ) ).divideBy( p(
                                                identifier( "H1" )
                                                .add( identifier( "H2" ) ) ) ) ) ), "similarity" ) ).toString() );
    }
}
TOP

Related Classes of org.neo4j.cypherdsl.CypherCookbookTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.