SE3353-assignment8

简单总结一下这次作业。基于MongoDB和Neo4j的存储功能。

1
2
	1.将你认为合适的内容改造为在MongoDB中存储,例如书的产品评价或书评。你可以参照课程样例将数据分别存储在MySQL和MongoDB中,也可以将所有数据都存储在MongoDB中,如果采用后者,需要确保系统功能都能正常实现,包括书籍浏览、查询、下订单和管理库存等。
​ 2.为你的每一本图书都添加一些标签,在Neo4J中将这些标签构建成一张图。在系统中增加一项搜索功能,如果用户按照标签搜索,你可以将Neo4J中存储的与用户选中的标签以及通过2重关系可以关联到的所有标签都选出,作为搜索的依据,在MySQL中搜索所有带有这些标签中任意一个或多个的图书,作为图书搜索结果呈现给用户。

​ 最近有点眼高手低,有些技术以前用过就自以为可以不必记录下来了。要遏制住这股风气,因为我并不了解任何工具的底层、实现也全靠CSDN,哪怕为了第二次复现起来、第二次快速回忆起现在做的事情,也需要详尽地写下目前的操作。

PART1:MongoDB

首先是安装并运行MongoDB,在安装目录下,先运行mongod.exe,再运行mongo.exe即可看到如下的命令行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---
> 2 + 2
4
> db.runoob.insert({x:10})
WriteResult({ "nInserted" : 1 })
> db.runoob.find()
{ "_id" : ObjectId("6190c5a1e7f64d1430e95cde"), "x" : 10 }
> db.auth("root","123456")
Error: Authentication failed.
0
> use admin
switched to db admin
> db.createUser({user:"root",pwd:"1234",roles:[{"role":"readWrite","db":"demo"}]})
Successfully added user: {
"user" : "root",
"roles" : [
{
"role" : "readWrite",
"db" : "demo"
}
]
}
> db.auth("root","1234")
1

​ 我们在书店的DAO层中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public Book addRemark(Long book_id, String remark) {
Book book = findOne(book_id);
Remark remarks = book.getRemark();
if (remarks == null) {
remarks = new Remark(book.getId());
}
else {
remarkRepository.delete(book.getRemark());
}
remarks.addRemark(remark);
book.setRemark(remarks);
save(book);
return book;
}

​ 因为MongoDB不支持相同id的document的覆盖操作,所以我们每次取出来就删除掉,然后再把新的评论加上后再save到collection中,唯一的问题可能就是在delete后save前如果server crash了,可能会导致这个书籍的评论消失。可以通过额外的数据备份机制来避免这个情况。

​ 使用ROBO3T可以看到,确实我们每次添加一条评论,就自动添加到Collection对应book id的document下了。

image-20211117120133667

PART2:Neo4j

​ 按照Neo4j desktop很快,但是把它在SpringBoot中调通用了很大波折。我发现只要加入spring-boot-starter-data-neo4j这个依赖,启动后就会报如下的错。

1
2
3
4
5
6
7
8
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reactiveNeo4jTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/neo4j/Neo4jReactiveDataAutoConfiguration.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.springframework.data.neo4j.core.ReactiveNeo4jTemplate] from ClassLoader 
...
Caused by: java.lang.ClassNotFoundException: reactor.util.context.ContextView
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_91]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_91]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_91]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_91]
... 26 common frames omitted

​ 依赖也没冲突,代码都没开始写,就出这个问题,真的卡了好几个小时。后来不抱希望地看到了这个issue,添加了依赖:

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/io.projectreactor.netty/reactor-netty -->
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>1.0.13</version>
</dependency>

​ 居然就能用了,真是百思不得其解。

image-20211117115110854

可见成功初始化,创建了由书籍和标签构成的一张图。

我们如下extend Neo4jRepository

1
2
3
4
5
6
public interface BookNodeRepository extends Neo4jRepository<BookNode, Long> {
BookNode findByName(String name);
BookNode findByTagNodesName(String name);
@Query("MATCH (p:BookNode) -[:contain]->(p1:TagNode)<-[:contain]- (p2:BookNode) where p.name=~ $n return p2")
List<BookNode> findByTwoRelationship(@Param("n") String n);
}

image-20211117114848991

和我们在Neo4j Desktop中查询到的完全一样

image-20211117114910052

Customizing Query by @Query annotation

Author

Kami-code

Posted on

2021-11-22

Updated on

2022-01-19

Licensed under

Comments