Skip to content

Not able to retrieve grand ancestor attributes overriden/included in current node data #2119

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wolfy027 opened this issue Jan 18, 2021 · 5 comments
Assignees
Labels
status: waiting-for-triage An issue we've not yet triaged

Comments

@wolfy027
Copy link

wolfy027 commented Jan 18, 2021

Custom Query used in AnimalRepository > @query:

MATCH (c:Animal {uuid: $id}) OPTIONAL MATCH path=(c)-[r:PARENT]->(p:Animal) RETURN path,collect(r),collect(p)
Spring Boot Version before update : 2.3.4

Spring Boot Version before update : 2.4.1

Domain reference:

@Node
@JsonSerialize(as = Animal.class)
@JsonDeserialize(as = Animal.class)
public class Animal{
@Id
@GeneratedValue(generatorClass = GeneratedValue.UUIDGenerator.class)
private UUID uuid;
 
@Relationship(type = "PARENT", direction = Relationship.Direction.OUTGOING)
private Animal parent;

 @CompositeProperty
 private Map<String, String> attributes;

   public Map<String, String> getAttributes()
    {
        return attributes;
    }

    public Animal setAttributes(final Map<String, String> attributes)
    {
        this.attributes = attributes;
        return this;
    }
..
..
}

This gives me response with attributes of current node and it's parent's nodes, but it skips the grand-parent's attributes.

MATCH (c:Animal {uuid: $id}) OPTIONAL MATCH path=(c)-[r:PARENT*]->(p:Animal) RETURN path,collect(r),collect(p) does'nt work

What should be the suggested change?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jan 18, 2021
@meistermeier
Copy link
Collaborator

Just commented on the other issue with the same reply because I haven't seen this issue first. Please feel free to ignore the comment over there ;)
Could you set the SDN version to 6.0.3 in your pom?
There were several fixes targeting inheritance.

@meistermeier meistermeier self-assigned this Jan 19, 2021
@wolfy027
Copy link
Author

wolfy027 commented Jan 19, 2021

After setting SDN to 6.0.3 with spring-boot 2.4.1, there is no effect on the outcome.
The direct parent attributes are mapped in the child node attributes(map), but it does not include grand parent attributes(map) properties.
Query Used :

 MATCH (c:Animal {uuid: $id})  
OPTIONAL MATCH path=(c:Animal)-[:PARENT*0..]->(p:Animal)  
WITH *, relationships(path) as r  
RETURN path,collect(r),collect(p)

Alternate Query used: also same outcome

 MATCH (c:Animal {uuid: $id})  
OPTIONAL MATCH path=(c:Animal)-[r:PARENT]->(p:Animal)
RETURN c,collect(r),collect(p)

Java snippet:

  final Stream<Animal> parentBranch = animalRepository.findParentBranch(id);

  final Animal myAnimal= parentBranch.filter(animal-> id.equals(animal.getId()))
            .findFirst().....

myAnimal.getAttributes() -> does not have grand-parent attribute map entries, but has parent ones

myAnimal.getParent().getParent() -> is null

@meistermeier

@meistermeier
Copy link
Collaborator

I am currently working on path related mapping improvements. There will be a fix coming up with the next service release to support a broader range of queries. e.g. something like this

MATCH (c:Animal {uuid: $uuid})
OPTIONAL MATCH path=(c:Animal)-[:PARENT*0..]->(p:Animal)
RETURN collect(path)

or because the optional path match with a starting 0 eliminates the OPTIONAL bit (AFAIK)

MATCH path=(c:Animal{uuid: $uuid})-[:PARENT*0..]->(p:Animal) RETURN collect(path)

will work.

I leave this issue open for now because I want to give you something that could help you in the meantime.

@wolfy027
Copy link
Author

wolfy027 commented Jan 22, 2021

Hello @meistermeier ,
Thanks very much for the response. I tried the suggested query with Spring boot 2.4.2, and this time only the child attributes are found , and all ancestor attributes along with parent/grand-parent ones are missing.
I the earlier case the parent attributes were found, Strangely odd to find this. Please notify in case that is the only solution, I can work with the updated version.

unit test logs -

**_Expecting map:
  <{"childAtt"="childValue", "overwrittenAtt"="overwrittenValue"}>
to contain only:
  <[MapEntry[key="grandParentAtt", value="grandParentValue"],
    MapEntry[key="parentAtt", value="parentValue"],
    MapEntry[key="overwrittenAtt", value="overwrittenValue"],
    MapEntry[key="childAtt", value="childValue"]]>
but could not find the following map entries:
  <[MapEntry[key="grandParentAtt", value="grandParentValue"],
    MapEntry[key="parentAtt", value="parentValue"]]>_**

@meistermeier
Copy link
Collaborator

As I said, the improvements for this will come in the next service release.
For now (and I do not even know why I started this in groovy):

@Query("MATCH path=(animal:Animal{id: \$id})-[:PARENT*0..]->(p:Animal) " +
        "WITH collect(path) as paths, animal " +
        "WITH animal, " +
        "reduce(a=[], node in reduce(b=[], c in [aa in paths | nodes(aa)] | b + c) | case when node in a then a else a + node end) as nodes, " +
        "reduce(d=[], relationship in reduce(e=[], f in [dd in paths | relationships(dd)] | e + f) | case when relationship in d then d else d + relationship end) as relationships " +
        "RETURN animal, nodes, relationships")
fun retrieveByPath(@Param("id") id: String) : List<Animal>

will do the job. It boils down the whole path mapping to a "root node, relationships, relatedNodes" pattern.

I verified this with

@Test
fun pathQuerying() {
    driver.session().use { session ->
        session.run("MATCH (n) detach delete n").consume()
        session.run("CREATE (:Animal{id:'test', `attributes.childAtt`: 'childValue'})-[:PARENT]->" +
                "(:Animal{id:'test2', `attributes.parentAtt`: 'parentValue'})-[:PARENT]->" +
                "(:Animal{id:'test3', `attributes.grandParentAtt`: 'grandParentValue'})").consume()
    }
    val animal = aRepository.retrieveByPath("test")
    assertThat(animal.get(0).attributes)
            .containsExactlyInAnyOrderEntriesOf(mapOf(Pair("childAtt","childValue")))
    assertThat(animal.get(0).parent!!.attributes)
            .containsExactlyInAnyOrderEntriesOf(mapOf(Pair("parentAtt","parentValue")))
    assertThat(animal.get(0).parent!!.parent!!.attributes)
            .containsExactlyInAnyOrderEntriesOf(mapOf(Pair("grandParentAtt","grandParentValue")))
}

meistermeier added a commit that referenced this issue Jan 25, 2021
Those queries will now return nodes and relationships instead of plain path(s).
This format is now the only one supported by SDN for generated queries.

Intentionally closes #2121
As a side-effect this commit also
closes #2107
closes #2109
closes #2119

Polishing after rebase.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

No branches or pull requests

3 participants