使用Redis存储来自neo4j的查询的结果

时间:2015-11-24 15:26:00

标签: node.js express neo4j redis

我在neo4j中有一些带有一些聚合函数的查询,大约需要10秒来检索信息。我想要做的是将查询结果存储到redis中,并且redis数据库会不时地更新neo4j的结果。

一条记录如下:

{ entry: "123", model: "abc", reactants: [{specie: "abc@12", color: "black"}], .... }

我正在使用带有express的node.js,提前感谢您的关注

更新:我的查询相当广泛,我不得不这样做'UNWIND'部分能够通过反应物进行搜索(我也想要产品,但我不知道该怎么做)。我不知道是否可以优化到至少2秒,但在这里:

MATCH (rx:ModelReaction),
      (rx)-[l:left_component]->(lc:MetaboliteSpecie), 
      (rx)-[r:right_component]->(rc:MetaboliteSpecie) 
      OPTIONAL MATCH (rx)-[:has_gpr]-(gpr:Root) 
      OPTIONAL MATCH (rx)-[:has_crossreference_to]-(cr)-[:has_ec_number]-(ec)
WITH rx,r,cr,ec,gpr, 
     COLLECT(DISTINCT {specie: l.cpdEntry, stoichiometry: l.stoichiometry}) as reacts 
UNWIND reacts as rcts 
WITH rx,r,cr,ec,gpr, rcts, reacts 
WHERE rcts.specie =~ {searchText} OR rx.entry =~ {searchText} OR 
      rx.name =~ {searchText} OR (ec.entry IS NOT NULL AND 
      ec.entry =~ {searchText}) OR rx.geneRule =~ {searchText} 
RETURN {entry: rx.entry, 
    reactants: reacts, 
    products:COLLECT(DISTINCT {specie: r.cpdEntry, 
                               stoichiometry: r.stoichiometry}), 
    orientation: rx.orientation, name: rx.name, ecnumber: ec.entry, 
    gpr_rule: rx.geneRule, gpr_normalized: gpr.normalized_rule}
    ORDER BY ' + reactionsTableMap[sortCol] + ' ' + order + ' SKIP {offset} LIMIT {number}'

1 个答案:

答案 0 :(得分:3)

最简单的方法是将Neo4j的结果存储为redis中的JSON字符串,并在该键上设置到期时间。现在,当您需要检索数据时,检查密钥是否存在,然后redis用作缓存,如果密钥不存在,则询问Neo4j,将结果存储在redis中并将其返回到Node.js程序

伪代码,因为我不知道有关Neo4J和Redis的Node.js细节:

var result = redis.get("Record:123")
if (result == null) {
    result = neo4j.query("...");
    redis.setex("Record:123", toJson(result), 10); // set with expiry time
}
return result;

Redis将处理到期日,因此您无需处理。

如果要将它们全部存储起来,可以将它们存储在LIST或ZSET中(例如按记录ID排序),只需调用redis LRANGE / ZRANGE来检索部分列表/集

列表示例:

var exist = redis.exist("Records"); // check if something stored in redis
if (!exist) {
    var queryResult = neo4j.query("...); // get a list of results from neo4j
    queryResult.foreach(result => redis.lpush("Records", toJson(result))); // add the results in the redis list
}
return redis.lrange("Records", 0, 50); // get the 50 first items

现在只需使用redis.lrange的两个参数,通过获取十个项目然后接下来的十个来迭代它。

您也可以致电redis EXPIRE在redis列表上设置到期时间。