Neo4j太多WITH条款 - 这是一个好习惯吗?

时间:2015-08-15 19:37:15

标签: neo4j cypher

每个人,

我使用Neo4j 2.2.3来模拟车辆销售情景。图的结构简述如下:

每辆车都是标有 VEHICLE 的节点,并具有以下属性

  1. 价格
  2. 里程
  3. 制造年度
  4. 其他与车辆相关的其他内容

    • 制作(每个制作一个节点,即MAKE {make:' AUDI'},制作{make:' BMW'}等)
    • 模型(每个模型一个节点,即MODEL(型号:' A5'},MODEL {型号:' 318i'}等)
    • 燃料类型(如上所述,燃料{类型:' DIELSE'},燃料{类型:' PETROL'}等)
    • Gearbox(GBOX {type:' AUTO'},GBOX {type:' MANUAL'}等)
    • 颜色(几个重要的颜色节点)
    • 其他

    上面有固定数量的节点, VEHICLE 节点有传入关系。

    我允许用户根据以上标准搜索车辆。用户可以通过价格,里程,制造年度搜索车辆,这是车辆的属性,因此,我不需要查找关系,查询将如下所示:

        MATCH (v:VEHICLE) WHERE  v.mileage >= 50000  AND v.mileage <= 100000 
    AND v.price >= 5000 AND v.price <= 40000 RETURN v AS vehicle
    

    OR搜索有更多条件,如下面的cypher所示

        MATCH (v:VEHICLE)-[r]->(info) WHERE  v.mileage >= 100000 AND 
    v.mileage <= 150000 AND v.price >= 90000 AND v.price <= 100000 
    WITH v,r,info MATCH(v)-[]->(color:VCOLOR{name:'RED'})  
    WITH v,r,info MATCH(v)-[]->(make:VMAKE{make:'TOYOTA'})  
    WITH v,r,info MATCH(v)-[]->(plateType:VPLATE_TYPE{type:'-2'})  
    WITH v,r,info MATCH(v)-[]->(cylinder:VCYLINDER{no:6})  
    WITH v,r,info MATCH(v)-[]->(gbox:VGBOX{type:'MANUAL'})  
    WITH v,r,info MATCH(v)-[]->(cond:VCONDITION{condition:'USED'})  
    RETURN v AS vehicle,COLLECT({type:type(r), data:info}) AS details
    

    根据用户在车辆搜索请求中包含的条件数动态创建查询。因此,如果我看到该用户包含的条件不属于车辆节点属性列表(即颜色或变速箱),那么我添加 WITH 子句。随着条件数量的增加, WITH 子句的数量会增加(即最多可能有10个条件)。

    只是想知道我是否正确使用 WITH 子句?我发现围绕 WITH 子句包围我很棘手。在某些时候,我还必须实现分页功能(不知道从哪里开始 - 也许是LIMIT关键字?)。

    谢谢。

1 个答案:

答案 0 :(得分:1)

关于 WITH 通常用于管道查询,在传递之前执行一些数据修改。我理解它,就像返回需要将输出传递给新查询(在下次匹配之前使用聚合函数或order和limits子句)。

关于您的查询,您没有对 with 子句执行任何操作,只需添加新匹配项。这可以在一开始就完成。我发现它更优雅。但是,您可以运行PROFILE以查看每个响应的方式(如果您可以写出结果,我会感激不尽)。我期望在之前的所有比赛中获得更好的表现。您还可以使用标签(即CREATE INDEX ON:VCOLOR(名称))索引匹配属性,以获得更好的结果。

MATCH (v:VEHICLE)-[r]->(info), 
(v)-->(color:VCOLOR{name:'RED'}),
(v)-->(make:VMAKE{make:'TOYOTA'}),
(v)-->(gbox:VGBOX{type:'MANUAL'}),
(v)-->(cond:VCONDITION{condition:'USED'})  
WHERE  v.mileage >= 100000 AND 
v.mileage <= 150000 AND v.price >= 90000 AND v.price <= 100000  
RETURN v AS vehicle,COLLECT({type:type(r), data:info}) AS details

对于您的上一个问题,可以使用SKIP和LIMIT进行分页,如您自己建议的那样。可以在此处找到一个示例:http://neo4j.com/docs/stable/query-skip.html#skip-return-middle-two