I have a query in neo4j with some aggregation functions, which takes around 10 seconds to retrieve the information. What I would like to do is store the query results into redis and from time to time the redis database would update the results from neo4j.
我在neo4j中有一些带有一些聚合函数的查询,大约需要10秒来检索信息。我想要做的是将查询结果存储到redis中,redis数据库会不时更新neo4j的结果。
One record will be like:
一条记录如下:
{ entry: "123", model: "abc", reactants: [{specie: "abc@12", color: "black"}], .... }
I'm using node.js with express, thank you in advance for your attention
我正在使用带有express的node.js,请提前感谢您的关注
UPDATE: my query is quite extensive, I had to do that 'UNWIND' part to be able to search by the reactants (I wanted the products too but I didn't know how to do it). I don't know if it's possible to be optimized to at least 2 seconds but here it goes:
更新:我的查询相当广泛,我不得不这样做'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 个解决方案
#1
3
The easiest is to store the result from Neo4j as a JSON string in redis, and set an expiry time on that key. Now when you need to retrieve the data, you check if the key is there, then redis serves as a cache, and if the key is not there, you ask Neo4j, store the result in redis and returns that to your Node.js program.
最简单的方法是将Neo4j的结果存储为redis中的JSON字符串,并在该键上设置到期时间。现在,当您需要检索数据时,检查密钥是否存在,然后redis用作缓存,如果密钥不存在,则询问Neo4j,将结果存储在redis中并将其返回到Node.js程序。
Pseudo code since I don't know Node.js specifics regarding Neo4J and Redis:
伪代码,因为我不知道关于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 will handle the expiry so you don't have to.
Redis将处理到期日,因此您不必这样做。
If you want to store them all, you can store them in a LIST or a ZSET (sorted set by record Id for example) and just call redis LRANGE
/ZRANGE
to retrieve a part of that list/set
如果要将它们全部存储起来,可以将它们存储在LIST或ZSET中(例如按记录ID排序),只需调用redis LRANGE / ZRANGE来检索该列表/集合的一部分
Example with list:
列表示例:
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
Now just iterate on that using the two parameters of redis.lrange
by getting the ten items then the next ten.
现在只需使用redis.lrange的两个参数迭代它,然后获取十个项目,接下来的十个项目。
You can also call redis EXPIRE
to set an expiry time on the redis list.
您也可以调用redis EXPIRE在redis列表上设置到期时间。
#1
3
The easiest is to store the result from Neo4j as a JSON string in redis, and set an expiry time on that key. Now when you need to retrieve the data, you check if the key is there, then redis serves as a cache, and if the key is not there, you ask Neo4j, store the result in redis and returns that to your Node.js program.
最简单的方法是将Neo4j的结果存储为redis中的JSON字符串,并在该键上设置到期时间。现在,当您需要检索数据时,检查密钥是否存在,然后redis用作缓存,如果密钥不存在,则询问Neo4j,将结果存储在redis中并将其返回到Node.js程序。
Pseudo code since I don't know Node.js specifics regarding Neo4J and Redis:
伪代码,因为我不知道关于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 will handle the expiry so you don't have to.
Redis将处理到期日,因此您不必这样做。
If you want to store them all, you can store them in a LIST or a ZSET (sorted set by record Id for example) and just call redis LRANGE
/ZRANGE
to retrieve a part of that list/set
如果要将它们全部存储起来,可以将它们存储在LIST或ZSET中(例如按记录ID排序),只需调用redis LRANGE / ZRANGE来检索该列表/集合的一部分
Example with list:
列表示例:
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
Now just iterate on that using the two parameters of redis.lrange
by getting the ten items then the next ten.
现在只需使用redis.lrange的两个参数迭代它,然后获取十个项目,接下来的十个项目。
You can also call redis EXPIRE
to set an expiry time on the redis list.
您也可以调用redis EXPIRE在redis列表上设置到期时间。