updated documentation, fixed page/sort-test asserts
This commit is contained in:
@@ -157,8 +157,10 @@ public class GraphRepositoryFactory extends RepositoryFactorySupport {
|
||||
}
|
||||
if (parameters.hasPageableParameter()) {
|
||||
final Pageable pageable = getPageable(args);
|
||||
baseQuery = addSorting(baseQuery, pageable.getSort());
|
||||
baseQuery = addPaging(baseQuery, pageable);
|
||||
if (pageable!=null) {
|
||||
baseQuery = addSorting(baseQuery, pageable.getSort());
|
||||
baseQuery = addPaging(baseQuery, pageable);
|
||||
}
|
||||
}
|
||||
return baseQuery;
|
||||
}
|
||||
|
||||
@@ -34,12 +34,15 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.internal.matchers.IsCollectionContaining.hasItem;
|
||||
import static org.junit.internal.matchers.IsCollectionContaining.hasItems;
|
||||
import static org.neo4j.helpers.collection.IteratorUtil.asCollection;
|
||||
|
||||
@@ -92,23 +95,23 @@ public class GraphRepositoryTest {
|
||||
public void testFindPaged() {
|
||||
final PageRequest page = new PageRequest(0, 1, Sort.Direction.ASC, "member.name");
|
||||
Page<Person> teamMemberPage1 = personRepository.findAllTeamMembersPaged(page, testTeam.sdg);
|
||||
assertThat(teamMemberPage1, is((Iterable) asList(testTeam.david)));
|
||||
assertThat(teamMemberPage1, hasItem(testTeam.david));
|
||||
}
|
||||
@Test
|
||||
@Transactional
|
||||
public void testFindPagedDescending() {
|
||||
final PageRequest page = new PageRequest(0, 2, Sort.Direction.DESC, "member.name");
|
||||
Page<Person> teamMemberPage1 = personRepository.findAllTeamMembersPaged(page, testTeam.sdg);
|
||||
assertThat(teamMemberPage1, is((Iterable) asList(testTeam.michael, testTeam.emil)));
|
||||
assertEquals(asList(testTeam.michael, testTeam.emil), asCollection(teamMemberPage1));
|
||||
assertThat(teamMemberPage1.isFirstPage(), is(true));
|
||||
}
|
||||
@Test
|
||||
@Transactional
|
||||
public void testFindPagedNull() {
|
||||
Page<Person> teamMemberPage1 = personRepository.findAllTeamMembersPaged(null, testTeam.sdg);
|
||||
assertThat(teamMemberPage1, is((Iterable) asList(testTeam.michael, testTeam.emil)));
|
||||
assertEquals(asList(testTeam.michael, testTeam.emil,testTeam.david), asCollection(teamMemberPage1));
|
||||
assertThat(teamMemberPage1.isFirstPage(), is(true));
|
||||
assertThat(teamMemberPage1.isLastPage(), is(true));
|
||||
assertThat(teamMemberPage1.isLastPage(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -116,7 +119,7 @@ public class GraphRepositoryTest {
|
||||
public void testFindSortedDescending() {
|
||||
final Sort sort = new Sort(Sort.Direction.DESC, "member.name");
|
||||
Iterable<Person> teamMembers = personRepository.findAllTeamMembersSorted(testTeam.sdg, sort);
|
||||
assertThat(teamMembers, is((Iterable)asList(testTeam.michael, testTeam.emil, testTeam.david)));
|
||||
assertEquals(asList(testTeam.michael, testTeam.emil, testTeam.david), asCollection(teamMembers));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -117,5 +117,12 @@ public void foo( @Context WorldRepository repo ) {
|
||||
</example>
|
||||
Your project is now set up to work against a remote Neo4j Server.
|
||||
</para>
|
||||
<para>
|
||||
The remote REST implementation works for both the Neo4jTemplate as well as the GraphEntities. For traversals
|
||||
and cypher-graph-queries it is sensible to forward those to the remote and execute them there instead of
|
||||
walking the graph over the wire. RestGraphDatabase already supports that by providing methods that forward
|
||||
to the remote instance. (e.g. <code>queryEngineFor(), index() and createTraversalDescription()</code>).
|
||||
Please use those methods when interacting with a remote server for optimal performance.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -113,6 +113,24 @@
|
||||
<para><code>Iterable<EntityPath> findAllPathsByTraversal(traversalDescription)</code></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Executes the given query, replacing the first %d with the node-id and returning the results converted to the target type.</term>
|
||||
<listitem>
|
||||
<para><code><T> Iterable<T> NodeBacked.findAllByQuery(final String query, final Class<T> targetType)</code></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Executes the given query, replacing the first %d with the node-id and returning the original result, but with nodes and relationships replaced by their appropriate entities.</term>
|
||||
<listitem>
|
||||
<para><code>Iterable<Map<String,Object>> NodeBacked.findAllByQuery(final String query)</code></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Executes the given query, replacing the first %d with the node-id and returns a single result converted to the target type.</term>
|
||||
<listitem>
|
||||
<para><code><T> T NodeBacked.findByQuery(final String query, final Class<T> targetType)</code></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
<!--<code>@Query(query="{name:%s}") findByName(name)</code>)-->
|
||||
<!--</para>-->
|
||||
<!--</note>-->
|
||||
<para>
|
||||
Spring Data Graph repositories support annotated and named queries for the Neo4j
|
||||
<ulink url="http://docs.neo4j.org/chunked/milestone/query-lang.html">Cypher</ulink> query-language.
|
||||
</para>
|
||||
<para>
|
||||
Spring Data Graph comes with typed repository implementations that provide methods for
|
||||
locating node and relationship entities. There are 3 types of basic repository interfaces
|
||||
@@ -123,6 +127,66 @@
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Cypher-Queries</title>
|
||||
<section>
|
||||
<title>Annotated Queries</title>
|
||||
<para>
|
||||
Queries for the graph-query language cypher can be supplied with the <code>@GraphQuery</code> annotation.
|
||||
That means every method annotated with <code>@GraphQuery("start n=(%d) match (n)-->(m) return m")</code>
|
||||
will use the query string. The String-format parameters are replaced by the actual method parameters in order,
|
||||
whereby Node and Relationship-Entities are resolved to their respective id's and all other parameters are
|
||||
replaced directly (i.e. Strings, Longs, etc). There is special support for the <code>Sort</code> and <code>Pageable</code>
|
||||
parameters from Spring Data Commons, which are supported to add programmatic paging and sorting (alternatively
|
||||
static paging and sorting can be supplied in the query string itself).
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Named Queries</title>
|
||||
<para>Spring Data Graph also supports the notion of named queries which are externalized in property-config-files
|
||||
(<code>META-INF/graph-named-queries.properties</code>). Those files have the format:
|
||||
<code>Entity.finderName=query</code> (e.g. <code>Person.findBoss=start p=(%d) match (p)<-[:BOSS]-(boss) return boss</code>).
|
||||
Otherwise named queries support the same parameters as annotated queries.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Query results</title>
|
||||
<para>Typical results for queries are <code>Iterable<Type>, Iterable<Map<String,Object>>, Type and Page<Type></code>.
|
||||
Nodes and Relationships are converted to their respective Entities (if they exist). Other values are converted
|
||||
using the registered Spring conversion services (e.g. enums).
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Cypher Examples</title>
|
||||
<para>There is a <ulink url="http://neo4j.vidcaster.com/U2Y/introduction-to-cypher">screencast</ulink> available showing many features of the query language.
|
||||
The following examples are taken from the cineasts dataset of the tutorial section.
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><code>start n=(0) return n</code></term>
|
||||
<listitem><para>returns the node with id 0</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>start movie=(Movie,title,'Matrix') return movie</code></term>
|
||||
<listitem><para>returns the nodes which are indexed as 'Matrix'</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>start movie=(Movie,title,'Matrix') match (movie)<-[:ACTS_IN]-(actor) return actor.name</code></term>
|
||||
<listitem><para>returns the names of the actors that have a ACTS_IN relationship to the movie node for matrix</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>start movie=(Movie,title,'Matrix') match (movie)<-[r,:RATED]-(user) where r.stars > 3 return user.name, r.stars, r.comment</code></term>
|
||||
<listitem><para>returns users names and their ratings (>3) of the movie matrix</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><code>start user=(User,login,'micha') match (user)-[:FRIEND]-(friend)-[r,:RATED]->(movie) return movie.title, AVG(r.stars), count(*) order by AVG(r.stars) desc, count(*) desc</code></term>
|
||||
<listitem><para>returns the movies rate by the friends of the user 'micha', aggregated by movie.title, with averaged ratings and rating-counts sorted by both</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Creating repositories</title>
|
||||
<para>
|
||||
|
||||
Reference in New Issue
Block a user