注意:
1、使用jpa处理数据时,如果对象中有 relationship 关系,数据中没有写关系,更新数据时会将原有的关系删除掉(出来方法可以先查询出原来的数据,然后在编辑)
2、
集成
添加依赖
org.springframework.boot
spring-boot-starter-data-neo4j
spring:
# neo4j 图数据库
neo4j:
uri: bolt://localhost:7687
authentication:
username: neo4j
password: admin
# 指定数据库
data:
neo4j:
database: neo4j
如果和数据库一起集成,需要配置多数据源事务,不然事务会失效
import org.neo4j.driver.Driver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.neo4j.core.transaction.Neo4jTransactionManager;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.transaction.ChainedTransactionManager;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/**
* 配置neo4j 和 mysql 事务
* 1、@EnableNeo4jRepositories 用于扫描指定包下的repository
* 2、@EntityScan 用于扫描 neo4j实体类
*/
@Configuration
@EnableTransactionManagement
@EnableNeo4jRepositories(basePackages = {"com.graph.repository"})
@EntityScan(basePackages = {"com.graph.model.neo4j"})
public class Neo4jConfig {
/**
* 此处为了修改默认事务,必须改。
* 加载了Neo4J依赖库之后,transactionManager变成Neo4jTransactionManager
*
* @param dataSource 数据源
* @return
*/
@Bean("transactionManager")
@Primary
public DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
/**
* Neo4J的事务管理
*
* @param driver
* @return
*/
@Bean("neo4jTransactionManager")
public Neo4jTransactionManager neo4jTransactionManager(Driver driver) {
return new Neo4jTransactionManager(driver);
}
/**
* 需要使用多种事务时
*
* @param neo4jTransactionManager
* @param mysqlTransactionManager
* @return
*/
@Autowired
@Bean(name = "multiTransactionManager")
public PlatformTransactionManager multiTransactionManager(
Neo4jTransactionManager neo4jTransactionManager,
DataSourceTransactionManager mysqlTransactionManager) {
return new ChainedTransactionManager(
neo4jTransactionManager, mysqlTransactionManager);
}
}
1.使用Neo4jRepository 进行查询,可以使用jpa进行查询
@Transient注解是JPA框架提供的注解,用于显式告框架某个字段不需要被持久化
import lombok.Data;
import org.springframework.data.neo4j.core.schema.GeneratedValue;
import org.springframework.data.neo4j.core.schema.Id;
import org.springframework.data.neo4j.core.schema.Node;
import org.springframework.data.neo4j.core.schema.Property;
/**
* 文献
*
* @author kou
*/
@Data
@Node(labels = "文献")
public class Literature {
@Id
@GeneratedValue
private Long id;
@Property(name = "name")
private String name;
/**
* 文件路径
*/
@Property(name = "url")
private String url;
/**
* 作者列表(查询使用不需要持久化到数据库)
*/
@Transient
private List authors;
/**
* 期刊列表
*/
@Transient
private List journals;
}
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;
/**
* 文献表格
*/
@Data
public class LiteratureExcel {
/**
* 文献类型
*/
@ColumnWidth(20)
@ExcelProperty("文献类型")
private String documentType;
/**
* 文献名
*/
@ColumnWidth(60)
@ExcelProperty("文献名")
private String name;
/**
* 作者
*/
@ColumnWidth(60)
@ExcelProperty("作者")
private String authors;
/**
* 期刊
*/
@ColumnWidth(60)
@ExcelProperty("期刊")
private String journals;
/**
* 发表日期
*/
@ColumnWidth(20)
@ExcelProperty("发表日期")
private String publicationDate;
}
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.neo4j.repository.query.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 文献 持久层
*
* @author kou
*/
@Repository
public interface LiteratureRepository extends Neo4jRepository {
/**
* 按名称查询
*
* @param name 名称
* @return 结果
*/
List findByName(@Param("name") String name);
/**
* 按名称模糊查询
*
* @param name 名称
* @return 结果
*/
List findByNameLike(@Param("name") String name);
/**
* 分页查询
*
* @param name 名称
* @param pageable 分页条件
* @return 结果
*/
Page findByNameLike(@Param("name") String name, Pageable pageable);
@Query(value = "WITH $keyword AS keywords " +
" match (n:`文献`) " +
" WHERE ALL(keyword IN split(keywords, ' ') WHERE ANY(prop IN keys(n) WHERE n[prop] CONTAINS keyword))" +
" return n" +
" SKIP $skip LIMIT $limit ",
countQuery = "WITH $keyword AS keywords " +
" match (n:`文献`) " +
" WHERE ALL(keyword IN split(keywords, ' ') WHERE ANY(prop IN keys(n) WHERE n[prop] CONTAINS keyword))" +
" return count(*)"
)
Page findByKeyword(@Param("keyword") String keyword, @Param("pageable") Pageable pageable);
/**
* 文献搜索通过重要性排序
* 智能搜索(通过关键字搜索文献,作者,期刊,通过期刊因子或者文献日期进行排序)
*
* @param keyword 关键字
* @param ranges 搜索范围
* @param pageable 分页查询
* @return 结果
*/
@Query(value =
"optional match (n:`文献`) " +
"where " +
" ($ranges is null OR n.document_type in $ranges) " +
" and ( " +
" n.name CONTAINS $keyword "+
" or n.caption CONTAINS $keyword " +
" or n.abstracts CONTAINS $keyword " +
" or n.keyWords CONTAINS $keyword " +
" ) " +
"optional match(n)-[]-(j1:`期刊`) " +
"with collect({literature:n, journal:j1, author_index: null}) as rows1 " +
"optional match (j2:`期刊`)<-[:`发表期刊`]-(w2:`文献`) " +
"where j2.name CONTAINS $keyword " +
"with rows1, collect({literature:w2, journal:j2, author_index: null}) as rows2 " +
"optional match (a1:`作者`)<-[ra]-(w3:`文献`) " +
"where a1.name CONTAINS $keyword " +
"with rows1, rows2, w3, ra.index as author_index " +
"optional match (w3)-[]-(j3:`期刊`) " +
"with rows1, rows2, collect({literature:w3, journal:j3, author_index: null}) as rows3 " +
"with rows1 + rows2 + rows3 as rows " +
"unwind rows as row " +
"with row.literature as literature, row.journal as journal, row.author_index as author_index " +
"order by " +
" journal.composite_impact_factor desc, author_index asc " +
"return distinct literature " +
" SKIP $skip LIMIT $limit ",
countQuery = "optional match (n:`文献`) " +
"where " +
" ($ranges is null OR n.document_type in $ranges) " +
" and ( " +
" n.name CONTAINS $keyword "+
" or n.caption CONTAINS $keyword " +
" or n.abstracts CONTAINS $keyword " +
" or n.keyWords CONTAINS $keyword " +
" ) " +
"optional match(n)-[]-(j1:`期刊`) " +
"with collect({literature:n, journal:j1, author_index: null}) as rows1 " +
"optional match (j2:`期刊`)<-[:`发表期刊`]-(w2:`文献`) " +
"where j2.name CONTAINS $keyword " +
"with rows1, collect({literature:w2, journal:j2, author_index: null}) as rows2 " +
"optional match (a1:`作者`)<-[ra]-(w3:`文献`) " +
"where a1.name CONTAINS $keyword " +
"with rows1, rows2, w3, ra.index as author_index " +
"optional match (w3)-[]-(j3:`期刊`) " +
"with rows1, rows2, collect({literature:w3, journal:j3, author_index: author_index}) as rows3 " +
"with rows1 + rows2 + rows3 as rows " +
"unwind rows as row " +
"with row.literature as literature, row.journal as journal, row.author_index as author_index " +
"return count(distinct literature) "
)
Page findByKeywordByImportance(@Param("keyword") String keyword, @Param("ranges") List ranges, Pageable pageable);
/**
* 文献搜索通过相关性
* 智能搜索(通过关键字搜索文献,作者,期刊,通过期刊因子或者文献日期进行排序)
*
* @param keyword 关键字
* @param ranges 搜索范围
* @param pageable 分页查询
* @return 结果
*/
@Query(value =
"optional match (n:`文献`) " +
"where