有些人可能会认为这是programmers.stackexchange.com的问题但是,在阅读了Stack Overflow的Help Center后,我认为这是一个特定的编程问题,我更有可能在这里得到回复。
我有一个使用ExpressJS和Neo4j数据库作为后端的webapp。我有一个搜索屏幕,我想利用Neo4j关系的力量。搜索屏幕接受一个或多个值(即制造年份,燃料类型,变速箱等等),然后向ExpressJS发出请求,我使用POST请求的参数构建一个密码查询,如下所示:
MATCH
(v:VEHICLE),(v)-[:VGEARBOX_IS]->(:VGBOX{type:'MANUAL'}),
(v)-[:VCONDITION_IS]->(:VCONDITION{condition:'USED'})
WITH DISTINCT v
WHERE v.manufacture_year = 1990
MATCH (v)-[r]->(info)
RETURN v AS vehicle, COLLECT({type:type(r), data:info}) AS details
假设运行以上查询,返回以下三种车辆及其属性
如果结果超过20辆,那么我想对结果进行分页并且我知道它是如何工作的,我们使用SKIP和LIMIT,如下所示:
MATCH
(v:VEHICLE)
OPTIONAL MATCH (v)-[r:VFUEL_TYPE|:VGEARBOX_IS|:VHAVING_COLOR|...]->(info)
RETURN
v.vehicle_id AS vehicle_id,
v.engine_size AS engine_size,
v.published_date AS published_date,
COUNT(v) AS count,
COLLECT({type:type(r), data:info}) as data
ORDER BY v.published_date DESC
SKIP 20
LIMIT 16
这是工作流程,
我的问题是,保存搜索请求(或原始请求生成的密码)的最佳方法是什么,这样当用户点击下一页/上一页时,我会用不同的SKIP重新运行原始搜索密码查询值?每次用户进入下一页/上一页时,我都不想发出新的POST请求。这个问题可以通过以下方式解决,但不确定哪个更适合性能?
我确信有人会以有效的方式遇到这个问题,这就是我在这里发布问题的原因。请告知我如何才能最好地解决这个问题。
答案 0 :(得分:1)
就性能而言,首先应该使用Cypher parameters。这是一种将查询字符串与动态数据分开的方法。这样做的好处是可以防止注入攻击,但它的性能也更高,因为如果查询字符串没有更改,Neo4j可以缓存查询的查询计划并反复使用它。使用参数,您的第一个查询将如下所示:
public function fetchAllRows($table, $rowOrder, $direction,$con)
你的Neo4j javascript库应该允许你传递一个单独的对象。这是json中表示的对象:
MATCH
(v:VEHICLE),(v)-[:VGEARBOX_IS]->(:VGBOX{type: {vgearbox_type}}),
(v)-[:VCONDITION_IS]->(:VCONDITION{condition: {vcondition}})
WITH DISTINCT v
WHERE v.manufacture_year = {manufacture_year}
MATCH (v)-[r]->(info)
RETURN v AS vehicle, COLLECT({type:type(r), data:info}) AS details
SKIP ({page} - 1) * {per_page}
LIMIT {per_page}
每次从Node向数据库进行新查询时,我都没有发现太多问题。您应该确定实际需要多长时间才能确定它是否确实存在问题。
如果您希望通过缓存解决这个问题,则取决于您的服务器设置。如果节点应用程序和数据库位于同一台机器上或彼此非常接近,可能它并不重要。否则,您可以使用redis基于一个键进行缓存,该键是您要查询的值的组合。如果您考虑基于每个用户进行缓存,您甚至可以使用浏览器的本地存储,但用户是否经常反复访问相同的页面?您的数据的静态程度如何,数据因用户而异吗?