我目前正在对在关系数据库 (PostgreSQL) 和图形数据库 (Neo4j) 上运行的一些算法进行比较实验。 我将我的算法实现为 Neo4j 的用户定义过程,但它看起来不像是执行任何开箱即用的缓存。 有没有办法在 Neo4j 中为用户定义的过程配置缓存?
谢谢
最佳答案
如果缓存与您的用例相关并且您有一些要缓存的内容,则您必须自己实现缓存:可能与事务无关的内容,因此没有节点或关系; Neo4j id 很棘手,因为它们可以重复使用,所以最好只缓存它们一小段时间,或者根本不缓存。应用程序级 ID 就可以了,由字符串或标量类型组成的 bean 也可以。
假设您定义了这个过程:
public class MyProcedure {
@Context
public GraphDatabaseService db;
@Procedure
public Stream<MyBean> doSomething(@Name("uuid") String uuid) {
int count = 0;
// ...
return Stream.of(new MyBean(count));
}
public static class MyBean {
public int count;
public MyBean(int count) {
this.count = count;
}
}
}
您可以使用 ConcurrentMap
添加一些简单的缓存:
public class MyProcedure {
private static final ConcurrentMap<String, Collection<MyBean>> CACHE =
new ConcurrentHashMap<>();
@Context
public GraphDatabaseService db;
@Procedure
public Stream<MyBean> doSomething(@Name("uuid") String uuid) {
Collection<MyBean> result = CACHE.computeIfAbsent(uuid,
k -> doSomethingCacheable(k).collect(Collectors.toList()));
return result.stream();
}
private Stream<MyBean> doSomethingCacheable(String uuid) {
int count = 0;
// ...
return Stream.of(new MyBean(count));
}
public static class MyBean {
// ...
}
}
请注意,您无法缓存 Stream
因为它只能消耗一次,所以你必须自己收集到ArrayList
中来消耗它(您也可以将 collect
移到方法内部,将返回类型更改为 Collection<MyBean>
并使用方法引用)。如果该过程采用多个参数,则需要为复合键创建一个适当的类(如果可能,不可变的,具有正确的 equals
和 hashCode
实现)。 适用于可缓存值的限制也适用于键。
这是一个永恒的、无限的缓存。如果你需要更多的特性(过期,最大大小),我建议你使用真正的缓存实现,比如 Guava的 Cache
(或 LoadingCache
)或 Ben Manes 的 Caffeine .
关于database - Neo4j 用户定义过程的缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39738717/