这篇文章详细介绍了如何使用 Neo4j 构建推荐系统。重点是基于用户的阅读历史和评分推荐电影。内容涵盖了 Neo4j 的设置、通过 Neo4j 对象图映射器(Neo4j-OGM)将数据映射到 Java 中,以及编写用于推荐的 Cypher 查询。此外,还包括如何设置和使用 Neo4j 的云托管数据库服务 Neo4j Aura 的指导。
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-core</artifactId>
<version>3.2.31</version>
</dependency>
dbms.url=bolt://localhost:7687
dbms.username=neo4j
dbms.password=password
我使用 Neo4j 浏览器将数据添加到 Neo4j 数据库中。这涉及手动输入 Cypher 查询来创建节点和关系。例如:
CREATE (u2:User {id: 2, name: 'Bob'})
// Create Movies
CREATE (m1:Movie {id: 1, title: 'Inception', genre: 'Sci-Fi', rating: 9})
CREATE (m2:Movie {id: 2, title: 'The Matrix', genre: 'Sci-Fi', rating: 8})
CREATE (m3:Movie {id: 3, title: 'The Godfather', genre: 'Drama', rating: 10})
// Create Relationships
MATCH (u1:User {name: 'Alice'}), (m1:Movie {title: 'Inception'})
CREATE (u1)-[:LIKES]->(m1)
MATCH (u2:User {name: 'Bob'}), (m2:Movie {title: 'The Matrix'})
CREATE (u2)-[:LIKES]->(m2)
@NodeEntity
public class User {
@Id @GeneratedValue
private Long id;
private String name;
@Relationship(type = "LIKES", direction = Relationship.Direction.OUTGOING)
private Set<Movie> likedMovies = new HashSet<>();
}
@NodeEntity
public class Movie {
@Id @GeneratedValue
private Long id;
private String title;
private String genre;
}
import org.neo4j.ogm.config.Configuration;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
public class Neo4jConfig {
private static final String URL = "bolt://localhost:7687";
private static final String USER = "neo4j";
private static final String PASSWORD = "password";
private SessionFactory sessionFactory;
public Neo4jConfig() {
Configuration configuration = new Configuration.Builder()
.uri(URL)
.credentials(USER, PASSWORD)
.build();
this.sessionFactory = new SessionFactory(configuration, "your.package");
}
public Session getSession() {
return sessionFactory.openSession();
}
}
要执行推荐电影的 Cypher 查询,您可以使用 Neo4j 的 Java 驱动程序。确保您已将 Neo4j Java 驱动程序依赖项添加到您的 pom.xml 中:
<dependency>
<groupId>org.neo4j.driver</groupId>
<artifactId>neo4j-java-driver</artifactId>
<version>5.1.0</version>
</dependency>
以下是一个简洁的 Java 类,用于执行 Cypher 查询以获取推荐的电影:
import org.neo4j.driver.AuthTokens;
import org.neo4j.driver.Driver;
import org.neo4j.driver.GraphDatabase;
import org.neo4j.driver.Session;
import org.neo4j.driver.Result;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class RecommendationService {
private final Driver driver;
public RecommendationService(String uri, String user, String password) {
driver = GraphDatabase.driver(uri, AuthTokens.basic(user, password));
}
public void close() {
driver.close();
}
public List<String> getRecommendedMovies(Long userId) {
try (Session session = driver.session()) {
String query = "MATCH (u:User {id: $userId})-[:LIKES]->(m:Movie) " +
"WITH COLLECT(m.genre) AS likedGenres " +
"MATCH (m2:Movie) WHERE m2.genre IN likedGenres " +
"AND NOT EXISTS((u)-[:LIKES]->(m2)) " +
"RETURN m2.title AS recommendedMovie " +
"ORDER BY m2.rating DESC " +
"LIMIT 10";
return session.run(query, Map.of("userId", userId))
.list(record -> record.get("recommendedMovie").asString())
.stream()
.collect(Collectors.toList());
}
}
public static void main(String[] args) {
try (RecommendationService service = new RecommendationService("bolt://localhost:7687", "neo4j", "password")) {
service.getRecommendedMovies(1L).forEach(System.out::println);
}
}
}
MATCH (u:User)-[:LIKES]->(m:Movie)
WITH u, COLLECT(m.genre) AS likedGenres
MATCH (m2:Movie)
WHERE m2.genre IN likedGenres
RETURN m2.title AS recommendedMovie
此查询收集用户喜欢的电影类型,并推荐具有相似类型的其他电影。
MATCH (u:User)-[:LIKES]->(m:Movie)
WITH u, COLLECT(m.genre) AS likedGenres
MATCH (m2:Movie) WHERE m2.genre IN likedGenres AND NOT EXISTS((u)-[:LIKES]->(m2))
RETURN m2.title AS recommendedMovie
ORDER BY m2.rating DESC
LIMIT 10
此查询避免推荐用户已经喜欢的电影,并根据评分对建议进行排序。
dbms.url=bolt://<aura-uri>:7687
dbms.username=<username>
dbms.password=<password>
使用 Neo4j 和 Neo4j-OGM 构建推荐系统提供了一种强大且高效的方式,通过利用数据中固有的关系来提供个性化建议。通过将 Neo4j 的图数据库功能与 Java 中的 Neo4j-OGM 集成,您可以创建一个可扩展的推荐引擎,适应用户的偏好和行为。使用 Neo4j Aura 进行云托管确保了稳健性和可扩展性,使您能够轻松管理不断增长的数据集。