最后按号码排序

时间:2017-10-13 11:32:03

标签: neo4j cypher

我有一个neo4j数据库,它有近500k CK_ITEM个节点,定义如下:

CK_ITEM: {
    id (String),
    name (String),
    description (String)
}

假设我们有这样的样本数据:

+--------+----+-----------------+
|  name  | id | description     |
+--------+----+-----------------+
| Mark   | 1  | A lot of things |
| Gerald | 9  | Coff2e          |
| Carl   | 2  | 1 mango         |
| James  | 3  | 5 lemons        |
| Edward | 4  | Coffee          |
+--------+----+-----------------+

我需要按description ASC订购数据。这是我的问题:

MATCH (n:CK_ITEM)
ORDER BY
    n.description ASC

这导致:

+--------+----+-----------------+
|  name  | id | description     |
+--------+----+-----------------+
| Carl   | 2  | 1 mango         | <-- '1' < '5'
| James  | 3  | 5 lemons        | <-- '5' < 'A'
| Mark   | 1  | A lot of things | <-- 'A' < 'C'
| Gerald | 9  | Coff2e          | <-- '2' < 'e'
| Edward | 4  | Coffee          | 
+--------+----+-----------------+

现在,客户要求我订购结果,以便它们仍按升序排列,但数字是最后的。

基本上他希望结果如下:

+--------+----+-----------------+
|  name  | id | description     |
+--------+----+-----------------+
| Mark   | 1  | A lot of things |
| Edward | 4  | Coffee          |
| Gerald | 9  | Coff2e          | <-- Coff2e after Coffee
| Carl   | 2  | 1 mango         | <-- 1 and 5 ASC after everything
| James  | 3  | 5 lemons        |
+--------+----+-----------------+

转换为伪查询,它将是这样的:

MATCH CK_ITEM ORDER BY letters(description) ASC numbers(description) ASC

是否可以在单个查询中进行此类排序(字母优先升序,数字最后升序)?怎么样?

3 个答案:

答案 0 :(得分:1)

以下是Cypher查询,它将执行数字排在最后的排序(在每个字符位置)。

注意:这种方法并不高效,但如果您绝对需要,可以作为如何在Cypher中执行此操作的示例。

查询将每个description值拆分为单字符字符串,测试每个字符以查看它是否为数字,构造一个新字符串(逐个字符) - 用相应的UTF-16替换每个数字十六进制范围FFF6FFFF中的字符(这些是最高可能的UTF-16字符编码,并且您的原始数据不太可能已经使用它们),并使用该新字符串进行排序。

WITH {`0`:'\uFFF6',`1`:'\uFFF7',`2`:'\uFFF8',`3`:'\uFFF9',`4`:'\uFFFA',`5`:'\uFFFB',`6`:'\uFFFC',`7`:'\uFFFD',`8`:'\uFFFE',`9`:'\uFFFF'} AS big
MATCH (n:CK_ITEM)
WITH n, SPLIT(n.description, '') AS chars, big
RETURN n
ORDER BY
  REDUCE(s='', i IN RANGE(0, LENGTH(chars)-1) |
    CASE WHEN '9' >= chars[i] >= '0'
    THEN s + big[chars[i]]
    ELSE s + chars[i]
    END)

答案 1 :(得分:0)

您可以这样订购:

MATCH (n:CK_ITEM)
   RETURN n
ORDER BY
    substring(n.description,0,1) in ['0','1','2','3','4','5','6','7','8','9'], n.name

答案 2 :(得分:0)

您可以使用reqular表达式和UNION:

MATCH (n:CK_ITEM) WHERE NOT n.description =~ '[0-9].*'
RETURN n
ORDER BY
    n.description ASC

UNION

MATCH (n:CK_ITEM) WHERE n.description =~ '[0-9].*'
RETURN n
ORDER BY
    n.description ASC