[英]Custom queries don't work with interface projections in Spring Data Neo4j repositories
[英]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.