簡體   English   中英

自定義查詢預測 Spring 數據 neo4j:兩個相關節點包括關系

[英]Custom query projections with Spring Data neo4j: Two related nodes including the relationship

我正在努力了解投影在 Spring 數據 neo4j 中是如何工作的,或者更准確地說,可以用它們做什么以及有什么限制(即何時使用其他 forms 映射)。 這個主題有一些文檔或示例嗎?

這是我目前遇到的具體問題:我有節點通過代表它們相似性的關系鏈接。 當然,我想以盡可能少的查詢按關系排序列出它們。

這是查詢的一種方法

MATCH (evt1:Event)-[possibleDupe:POSSIBLE_DUPE]->(evt2:Event)
RETURN {evt1: evt1, possibleDupe: possibleDupe, evt2: evt2} AS duplicateEntry
ORDER BY possibleDupe.differenceScore

我以為我可以將其投影到 DTO:

public class DuplicateEntry {

    public DuplicateEntry(Event evt1, PossibleDupe possibleDupe, Event evt2) {
        this.evt1 = evt1;
        this.possibleDupe = possibleDupe;
        this.evt2 = evt2;
    }

    @Getter @Setter
    private Event evt1;

    @Getter @Setter
    private PossibleDupe possibleDupe;

    @Getter @Setter
    private Event evt2;

}

通常的方法是做這樣的事情:

Statement statement = CypherParser.parse("MATCH (evt1:Event)-[possibleDupe:POSSIBLE_DUPE]->(evt2:Event) RETURN evt1, possibleDupe, evt2");
repository.findAll(statement, Event.class);

但是那不能那樣映射,因為關系的兩邊有相同的類型,所以映射器不知道哪個是哪個: More than one matching node in the record.

這是 SDN 無法開箱即用的事情,因為域實體包裝器的這種外部視圖不適合以實體為中心的方法。

但是,您可以使用Neo4jClient手動查詢數據,並為您的節點實體 class 使用已經存在的映射器。

BiFunction<TypeSystem, MapAccessor, Event> mappingFunction = neo4jMappingContext.getRequiredMappingFunctionFor(Event.class);

client.query("MATCH (evt1:Event)-[possibleDupe:POSSIBLE_DUPE]->(evt2:Event) " +
        "RETURN {evt1: evt1, possibleDupe: possibleDupe, evt2: evt2} AS duplicateEntry" +
        "ORDER BY possibleDupe.differenceScore")
        .fetchAs(DuplicateEntry.class)
        .mappedBy((typeSystem, record) -> {
            var duplicateEntry = (Map<String, Object>) record.get("duplicateEntry");
            var event1 = mappingFunction.apply(typeSystem, duplicateEntry.get("evt1"));
            var event2 = mappingFunction.apply(typeSystem, duplicateEntry.get("evt2"));
            var possibleDupe = //... derive something from duplicateEntry.get("possibleDupe")
            return new DuplicateEntry(event1, possibleDupe, event2);
        }).all();

(剛剛寫的,可能有錯別字)

更多信息可以在這里找到: https://docs.spring.io/spring-data/neo4j/docs/current/reference/html/#neo4j-client.result-objects.mapping-functions

meistermeier 帶領我走上了正確的道路。 這是最終代碼。

數據傳輸組織:

public class DuplicateEntry {

    public DuplicateEntry(Event evt1, int differenceScore, Event evt2) {
        this.evt1 = evt1;
        this.differenceScore = differenceScore;
        this.evt2 = evt2;
    }

    @Getter @Setter
    private Event evt1;

    @Getter @Setter
    private int differenceScore;

    @Getter @Setter
    private Event evt2;

}

class 服務中查詢映射的代碼(我也加了分頁):

    public Collection<DuplicateEntry> getPossibleDupes(int page, int size) {

        BiFunction<TypeSystem, MapAccessor, Event> mappingFunction =
                       neo4jMappingContext.getRequiredMappingFunctionFor(Event.class);

        return neo4jClient.query("""
                        MATCH (evt1:Event)-[possibleDupe:POSSIBLE_DUPE]->(evt2:Event)
                        RETURN {evt1: evt1, possibleDupe: possibleDupe, evt2: evt2} AS duplicateEntry
                        ORDER BY possibleDupe.differenceScore
                        SKIP $skip LIMIT $size
                        """)
                .bind(size).to("size")
                .bind(page * size).to("skip")
                .fetchAs(DuplicateEntry.class)
                .mappedBy((typeSystem, record) -> {
                    MapValue duplicateEntry =  (MapValue) record.get("duplicateEntry");
                    var event1 = mappingFunction.apply(typeSystem, duplicateEntry.get("evt1"));
                    var event2 = mappingFunction.apply(typeSystem, duplicateEntry.get("evt2"));
                    return new DuplicateEntry(
                                   event1,
                                   duplicateEntry.get("possibleDupe")
                                        .get("differenceScore").asInt(), 
                                   event2);
                }).all();

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM