I try to add a method to my Neo4jRepository to find all nodes of a certain label, but I need to use a Projection because I don't want all data, but I cannot find a syntax that fits :
public List<PatternPreview> findAllProjectedBy();
This gives NullPointerException, I think because I don't have anything behind "By" (this one used to work with relational DB like Mysql that I used previously)
public List<PatternPreview> findAllProjected();
This gives Caused by: org.springframework.data.mapping.PropertyReferenceException: No property findAllProjected found for type Pattern!
public List<PatternPreview> findAll();
And this does not compile as it says The return type is incompatible with Neo4jRepository<Pattern,String>.findAll()
@gerrit.meier Is there any way to do this at the moment? I think my case is similar to Sabrina's, except I'm manually defining the query. Does the OGM have any way to map a projected node to a @NodeEntity? Just to be clear, I'm talking about this kind of thing:
MATCH (n:ContentSet)
RETURN n{ .uuid, .name } AS n
I can't find very much about this, but from what I know about OGM, this is not possible without new support e.g. in the ticket you posted. Is that correct, or I can I get around this somehow, even if I have to e.g. define new @NodeEntity (which I'm willing to do)?
Perhaps I'm misunderstanding your need, but it's possible to map a custom query directly to a pojo without using projection, NodeEntity, or QueryResult.
Set<EnrollmentGroup> groupMetadataEnrollmentGroups =
resultToSet(
session.query(
"MATCH (:GroupMetadata)-[:ENROLLMENT]->(eg:EnrollmentGroup) " +
"RETURN eg.type AS type, eg.name AS name, eg.relationship AS relationship, eg.node AS node " +
"ORDER BY name",
Collections.emptyMap()
),
EnrollmentGroup.class);
public class EnrollmentGroup {
private String type;
private String name;
private String node;
private String relationship;
}
public static <T> Set<T> resultToSet(Result result, Class<T> resultType) {
return new HashSet<>(ObjectUtils.jsonToList(
ObjectUtils.objectToJson(result),
resultType));
}
ObjectUtils is a homegrown class I won't elaborate upon, but the method names are self-explanatory.
Ah, very nice example, thanks @bierman.bob. That would work, if I had the time to change our fundamental patterns. But we use the native NodeEntity/RelationshipEntity across 100+ cases, on a deep tree of significantly complex nodes and relationships. For reference, here is a start on what the sparse/projected query might look like, and this is only a small part of it:
MATCH (cs:ContentSet)
OPTIONAL MATCH (cs)-[ptP:PRESENTS]->(pt:PersonaTemplate)
OPTIONAL MATCH (pt)-[itP:INTENDS]->(it:IntentTemplate)
OPTIONAL MATCH (it)-[itstP:PRESENTS]->(itst:SurveyTemplate)
OPTIONAL MATCH (pt)-[ptstP:PRESENTS]->(ptst:SurveyTemplate)
RETURN cs{ .uuid, .name } AS cs,
ptP,
pt{ .uuid, .name } AS pt,
itP,
it{ .uuid, .name } AS it,
itstP,
itst{ .uuid, .name } AS itst,
ptstP,
ptst{ .uuid, .name } AS ptst
I was looking for existing support to quickly define e.g. the "sparse" version of objects. Or some wishful cypher syntax to re-qualify a projected map to a known @NodeEntity, like RETURN n{ .uuid, .name } AS (:ContentSet). As far as I can tell, even "open projection" can't do what I need. So, I think I would have to go down the route you kindly suggested, or wait for unknown future support!
You're welcome, @Jiropole . We do have quite a few @NodeEntity and repo methods, but I ditched @QueryResult and projection early on. Although my example doesn't show it, many of our queries are custom and touch a lot of nodes, and this pattern has provided a flexible solution with minimal setup.