通过 neo4j 密码中的过滤器处理参数化顺序

Handling parameterised order by filters within neo4j cypher

我正在研究下面的密码,但我不确定如何实现参数化排序。我想使用参数 $field 和 $sort 进行排序,其中 $field 可以是:'species.name'、'species.description'、'species.scientificName'、'monthCount'、'eats' 或 'eatenBy' 而 $sort 只是 'asc' 或 'desc'。如果这些值中的任何一个是硬编码的,那么密码就会运行,但是当作为参数传递时它会失败。任何帮助将不胜感激! :)

MATCH (s:Species)
  WHERE toLower(s.name) CONTAINS toLower($search)

WITH s

OPTIONAL MATCH (s)-[e:EATS]->(eatsSpecies:Species)
OPTIONAL MATCH (s)<-[:EATEN_BY]-(eatenBySpecies:Species)
OPTIONAL MATCH (s)<-[:IS_ABOUT]-(image:Image)
OPTIONAL MATCH (s)-[:FALLS_UNDER]->(primary:Primary)
OPTIONAL MATCH (s)-[:MEASURED_BY]->(month:Month)

WITH s, eatsSpecies, eatenBySpecies, image, primary, month

WITH s,
     count(DISTINCT eatsSpecies.name) AS eats,
     count(DISTINCT eatenBySpecies.name) AS eatenBy,
     primary,
     image,
     count(distinct month) as monthCount

WITH {
       name:              s.name,
       scientificName:    s.scientificName,
       description:       s.description,
       primary:           case when exists(primary.GUID) then true else false end,
       active:            case when exists(s.active) then s.active else true end,
       months:            monthCount,
       guid:              s.GUID,
       eats:              eats,
       eatenBy:           eatenBy,
       image: case when exists(image.url) then true else false end
     } AS species order by $field $sort

SKIP $skip
LIMIT $limit

RETURN collect(species)

通过向对象添加一个 field 键并在 SKIPLIMIT

之前反转集合,这样的事情可能会起作用

下面的建议是纯粹的 Cypher。使用 apoc,您还可以创建动态查询。


MATCH (s:Species)
  WHERE toLower(s.name) CONTAINS toLower($search)

WITH s


OPTIONAL MATCH (s)-[e:EATS]->(eatsSpecies:Species)
OPTIONAL MATCH (s)<-[:EATEN_BY]-(eatenBySpecies:Species)
OPTIONAL MATCH (s)<-[:IS_ABOUT]-(image:Image)
OPTIONAL MATCH (s)-[:FALLS_UNDER]->(primary:Primary)
OPTIONAL MATCH (s)-[:MEASURED_BY]->(month:Month)

WITH s, eatsSpecies, eatenBySpecies, image, primary, month

WITH s,
     // add a 'sortField'
     s[$field] AS field,    
     count(DISTINCT eatsSpecies.name) AS eats,
     count(DISTINCT eatenBySpecies.name) AS eatenBy,
     primary,
     image,
     count(distinct month) as monthCount

WITH {
       name:              s.name,
       scientificName:    s.scientificName,
       description:       s.description,
       primary:           case when exists(primary.GUID) then true else false end,
       active:            case when exists(s.active) then s.active else true end,
       months:            monthCount,
       guid:              s.GUID,
       eats:              eats,
       eatenBy:           eatenBy,
       image: case when exists(image.url) then true else false end,
       field:            field
     } AS species ORDER BY species.field 

WITH COLLECT(species) AS sortedSpecies

RETURN CASE $sort 
           WHEN "asc" THEN sortedSpecies[$skip .. $limit]
           ELSE REDUCE(array=[], i IN RANGE(1,size(sortedSpecies)) |
                 array
                 +sortedSpecies[size(sortedSpecies)-i]
              )[$skip .. $limit]
       END AS sortedSpecies