Javascript 如何使用具有不同跳过值和限制值的同一查询对搜索结果进行分页
你们中的一些人可能会认为这是一个问题,但是,在通读了堆栈溢出之后,我相信这是一个特定的编程问题,我更可能在这里得到回答 我有一个webapp,它使用ExpressJS和Neo4j数据库作为后端。我有一个搜索屏幕,在那里我想使用Neo4j的关系的力量。搜索屏幕接受一个或多个值(即制造年份、燃油类型、变速箱等),然后向ExpressJS发出post请求,其中我使用post请求的参数构造一个密码查询,如下所示,作为示例:Javascript 如何使用具有不同跳过值和限制值的同一查询对搜索结果进行分页,javascript,express,neo4j,pagination,redis,Javascript,Express,Neo4j,Pagination,Redis,你们中的一些人可能会认为这是一个问题,但是,在通读了堆栈溢出之后,我相信这是一个特定的编程问题,我更可能在这里得到回答 我有一个webapp,它使用ExpressJS和Neo4j数据库作为后端。我有一个搜索屏幕,在那里我想使用Neo4j的关系的力量。搜索屏幕接受一个或多个值(即制造年份、燃油类型、变速箱等),然后向ExpressJS发出post请求,其中我使用post请求的参数构造一个密码查询,如下所示,作为示例: MATCH (v:VEHICLE),(v)-[:VGEARBOX_IS]-&
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 and 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
这是工作流程
- 用户导航到搜索屏幕,这是一个带有POST方法和各种输入字段的表单李>
- 用户选择一些他/她希望搜索的选项李>
- 然后,用户提交表单,表单向服务器发出post请求李>
- 该请求由一个路由处理,该路由使用请求的参数来构造如上所示的密码查询。它对Neo4j数据库运行cypher并接收结果李>
- 假设有200辆车与搜索结果匹配。然后我只想显示其中的20个结果,并提供下一个/上一个按钮李>
- 当用户看到前20个时,他/她希望看到下一个20,也就是说,我必须重新运行用户最初提交的相同查询,但跳过值为20(当用户导航到下一页时跳过值不断增加20,当移动到上一页时递减20)李>
我确信有人遇到了这个问题,并且以一种高效的方式解决了这个问题,这就是我在这里发布这个问题的原因。请告诉我如何才能最好地解决这个问题。就性能而言,您绝对应该做的第一件事就是使用。这是一种将查询字符串与动态数据分离的方法。这具有优势您可以防范注入攻击,但这也会提高性能,因为如果您的查询字符串不变,Neo4j可以为您的查询缓存查询计划,并反复使用它。使用参数,您的第一个查询将如下所示:
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}
Neo4j的javascript库应该允许您传递一个单独的对象。以下是用json表示的对象的外观:
{
"vgearbox_type": "MANUAL",
"vcondition": "USED",
"manufacture_year": 1990,
"page": 1,
"per_page": 20
}
我认为每次从节点对数据库进行新的查询并没有什么问题。您应该测试实际需要多长时间才能确定这是否真的是一个问题
如果您希望通过缓存来解决这一问题,则这取决于您的服务器设置。如果节点应用程序和数据库位于同一台计算机上或彼此非常接近,则这可能并不重要。否则,您可以使用redis根据您要查询的值的组合键进行缓存。如果您考虑的是cach基于每个用户,您甚至可以使用浏览器的本地存储,但用户是否经常反复访问相同的页面?您的数据有多静态?用户之间的数据是否不同?感谢cypher参数的建议,我肯定会研究注入问题。关于每次发布新帖子e user转到下一页/上一页,我应该如何保留原始请求中的post值?隐藏字段?会话?我建议在每篇post中发送所有表单参数。它不应该大大增加您的请求大小。这可能是隐藏字段,也可能是javascript的编写方式,具体取决于你正在写这篇文章。如果你使用类似会话的方式,我怀疑你会发现至少还有一个bug,否则你会试图跟踪事情。感谢你花时间回复这篇文章,这是有意义的。