在 spring-data-neo4j 自定义查询中映射其他属性

问题描述 投票:0回答:1

我正在尝试在 spring-data-neo4j (7.3.0) 环境中利用 Neo4J 向量相似性搜索功能。

以下是数据对象:

public record ScoredSnippet(Snippet snippet, Double score)

以及用于检索片段的存储库:

public interface SnippetRAGRepository extends ReactiveNeo4jRepository<ScoredSnippet, String>
{
    @Query("""
       MATCH (s:Snippet)
       WITH s, vector.similarity.cosine(s.embedding, toFloatList($embedding)) AS score
       RETURN s, score
       ORDER BY score DESC LIMIT $limit
       """)
    public Flux<ScoredSnippet> findBySemantics(double [] embedding, int limit );
}

当返回类型只是“Snippet”时,存储库和查询可以完美运行。 但是,当尝试返回 ScoredSnippet 时,我遇到以下情况:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'snippetRAGRepository' defined in ai.amber.core.snippets.SnippetRAGRepository defined in @EnableReactiveNeo4jRepositories declared on Neo4jReactiveRepositoriesRegistrar.EnableReactiveNeo4jRepositoriesConfiguration: Required identifier property not found for class ai.amber.core.snippets.ScoredSnippet
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:969) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962) ~[spring-context-6.1.8.jar:6.1.8]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.8.jar:6.1.8]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.0-SNAPSHOT.jar:3.3.0-SNAPSHOT]
    at ai.amber.core.Main.main(Main.java:15) ~[main/:na]
Caused by: java.lang.IllegalStateException: Required identifier property not found for class ai.amber.core.snippets.ScoredSnippet
    at org.springframework.data.mapping.PersistentEntity.getRequiredIdProperty(PersistentEntity.java:135) ~[spring-data-commons-3.3.0.jar:3.3.0]
    at org.springframework.data.repository.core.support.PersistentEntityInformation.getIdType(PersistentEntityInformation.java:58) ~[spring-data-commons-3.3.0.jar:3.3.0]
    at org.springframework.data.neo4j.repository.support.ReactiveNeo4jRepositoryFactory.getTargetRepository(ReactiveNeo4jRepositoryFactory.java:76) ~[spring-data-neo4j-7.3.0.jar:7.3.0]
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:317) ~[spring-data-commons-3.3.0.jar:3.3.0]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:286) ~[spring-data-commons-3.3.0.jar:3.3.0]
    at org.springframework.data.util.Lazy.getNullable(Lazy.java:135) ~[spring-data-commons-3.3.0.jar:3.3.0]
    at org.springframework.data.util.Lazy.get(Lazy.java:113) ~[spring-data-commons-3.3.0.jar:3.3.0]
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:292) ~[spring-data-commons-3.3.0.jar:3.3.0]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1835) ~[spring-beans-6.1.8.jar:6.1.8]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784) ~[spring-beans-6.1.8.jar:6.1.8]
    ... 16 common frames omitted

我认为使用投影应该能够提取此类复合对象,而无需将整个@Node骨架shebang分配给它们......

我尝试对 ScoredSnippet 使用接口、记录或普通 DTO 类。

实现这一目标的正确方法是什么?

spring-data-neo4j
1个回答
0
投票

实际上,我解决了这个问题: 首先,存储库仍应通过 Snippet 类型而不是 ScoredSnippet 进行定义:

公共接口 SnippetRAGRepository 扩展了 ReactiveNeo4jRepository

其次,Cypher 返回值应该正确命名:

RETURN 作为片段,得分

存储库方法的返回类型仍应为ScoredSnippet

© www.soinside.com 2019 - 2024. All rights reserved.