Spring Data | Neo4J | Querying for the path in the correct order

北城余情 提交于 2019-12-12 04:38:15

问题


Versions:

<dependency>
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm-core</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency> <!-- If you're using the HTTP driver -->
            <groupId>org.neo4j</groupId>
            <artifactId>neo4j-ogm-http-driver</artifactId>
            <version>2.1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-neo4j -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-neo4j</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

Here are my entities:

@Data
@NodeEntity
@EqualsAndHashCode(exclude = {"operatedByBuses"})
@ToString(of = {"name"})
public class BusStop {
    @GraphId
    private Long graphId;

    @Index(unique = true, primary = true)
    private String name;

    private String pincode;

    private String landmark;

    private String[] latlong;

    @Relationship(type = "OPERATED_BY")
    private Set<OperatedByBus> operatedByBuses = new HashSet<>();
}

@Data
@RelationshipEntity(type = "OPERATED_BY")
@ToString(of = "displayName")
public class OperatedByBus {

    @GraphId
    private Long id;

    @StartNode
    private BusStop origin;

    @EndNode
    private BusStop destination;
}

I'm trying to get the routes between A and D for which I need the result as A,B,C and D in the correct order and then I'll get the buses in each object.

This is my cypher:

String findBuses = "MATCH p=shortestPath((o:BusStop)-[buses*1..40]->(d:BusStop))\n" +
                "WHERE o.name =~ '(?i).*ABC Bus Stand.*'\n" +
                "  AND d.name =~ '(?i).*XYZ Bus Stand.*'\n" +
                "RETURN p";

        Iterable<BusStop> busstops = session.query(BusStop.class, findBuses, Collections.emptyMap());
        System.out.println(busstops);

        for (BusStop busStop : busstops) {
            System.out.println(busStop.getName());
            System.out.println("\t " + busStop.getOperatedByBuses());
        }

But the results are not in the right order. I see results as D,C,A,B (or some random order) as opposed to A,B,C,D.

One way I can think of is add an attribute to the OperatedByBus say int legId and then order by legId in my query. Not sure if this is the best way.

Anything I'm missing?


回答1:


Modify your query as follows:

MATCH p=shortestPath((o:BusStop)-[buses*1..40]->(d:BusStop))
WHERE 
  o.name =~ '(?i).*ABC Bus Stand.*' AND
  d.name =~ '(?i).*XYZ Bus Stand.*'
RETURN nodes(p) as busStops,relationships(p)

note that your query may return multiple rows, when the where clause matches multiple nodes.

Then use session.query(findBuses, Collections.emptyMap()); instead. The result type is org.neo4j.ogm.model.Result, use following to get individual results:

Iterable<Map<String, Object>> result.queryResults();
.. iterate over results
   // to get a `busStops` for single path as collection, which should be in order
   .. (Collection<BusStop>) item.get("busStops");


来源:https://stackoverflow.com/questions/46073027/spring-data-neo4j-querying-for-the-path-in-the-correct-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!